Skip to content

Add IPAddr#to_bits - #131

Merged
taketo1113 merged 1 commit into
ruby:masterfrom
taketo1113:add-to_bits
Oct 20, 2026
Merged

taketo1113 merged 1 commit into
ruby:masterfrom
taketo1113:add-to_bits

Conversation

@taketo1113

Copy link
Copy Markdown
Collaborator

This pull request adds IPAddr#to_bits, which returns a string containing the binary representation of the address (32 characters for IPv4, 128 for IPv6).

IPAddr.new("192.168.1.1").to_bits
# => "11000000101010000000000100000001"

IPAddr.new("3ffe:505:2::1").to_bits
# => "00111111111111100000010100000101000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000001"

Use case

When designing an IP address allocation scheme for an organization, there are
cases where you want to keep addresses human-readable while making sure the
scheme fits within the available bits. In such cases, having the address as a
binary string makes it easy to check the bit patterns while designing.

For example, consider a scheme based on 172.16.0.0/16:

  • The first 2 bits of the third octet select the usage category
    (e.g. management / tenant / reserved).
  • The remaining 6 bits of the third octet are the tenant ID.
  • Each tenant gets a /24, and the fourth octet is used for addresses within the tenant.
IPAddr.new("172.16.69.0").to_bits
# => "10101100000100000100010100000000"

Splitting that string according to the scheme above:

 10101100 00010000 01 000101 00000000
 ^^^^^^^^^^^^^^^^^ ^^ ^^^^^^ ^^^^^^^^
 |                 |  |      |
 |                 |  |      +-- 4th octet: addresses within the tenant (/24)
 |                 |  +--------- tenant ID (6 bits): 000101 (5)
 |                 +------------ category (2 bits): 01
 +------------------------------ fixed prefix: 172.16.0.0/16

Why not to_i.to_s(2)?

IPAddr#to_i.to_s(2) drops leading zeros, so the caller has to pad the result
to the address width (32 for IPv4, 128 for IPv6). That means code that handles
both families has to branch on the address family. to_bits hides this and
provides a common interface for IPv4 and IPv6:

IPAddr.new("0.0.0.1").to_i.to_s(2) # => "1"
IPAddr.new("::1").to_i.to_s(2)     # => "1"

IPAddr.new("0.0.0.1").to_bits    # => "00000000000000000000000000000001"
IPAddr.new("::1").to_bits.length # => 128

Related

Returns the binary representation of the address value as a string of
"0" and "1" characters, right adjusted to the address size (32
characters for IPv4, 128 for IPv6).
@taketo1113 taketo1113 self-assigned this Oct 19, 2026
@taketo1113
taketo1113 requested a review from knu as a code owner October 19, 2026 13:49
@taketo1113
taketo1113 merged commit 5e66612 into ruby:master Oct 20, 2026
29 checks passed
@taketo1113
taketo1113 deleted the add-to_bits branch October 20, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant