Created
June 19, 2015 19:52
-
-
Save flou/eff349acffbe93060327 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Network | |
# Create a new network | |
# @param address [String] the address of the network formatted as | |
# "10.0.0.0/16" or "10.0.0.0/255.255.255.0" | |
def initialize(address) | |
@address = address | |
@ip = to_binary(address.split("/")[0]) | |
@mask = to_binary(address.split("/")[1]) | |
end | |
# Returns the mask for the network in binary form | |
# @param format [Boolean] add dots (.) between bit groups | |
# @return [String] network mask in binary form | |
def mask(format: false) | |
format ? self.class.pretty_print_address(@mask) : @mask | |
end | |
# Returns the IP for the network in binary form | |
# @param format [Boolean] add dots (.) between bit groups | |
# @return [String] network IP in binary form | |
def ip(format: false) | |
format ? self.class.pretty_print_address(@ip) : @ip | |
end | |
# Returns the number of possible addresses in the network | |
# @return [Integer] Number of possible addresses in the network | |
def available_addresses | |
network = machine_part(mask, ip) | |
2 ** network.length | |
end | |
def self.mask_to_binary(mask = "/16", format: false) | |
mask.gsub!(/\//, "") if mask.start_with?("/") | |
bin = ("1" * mask.to_i).ljust(32, "0") | |
format ? pretty_print_address(bin) : bin | |
end | |
def self.mask_to_decimal(mask = "/16", format: false) | |
mask = mask_to_binary(mask, format: true) | |
# mask.gsub!(/\//, "") if mask.start_with?("/") | |
bin = mask.split(".").map { |c| c.to_i(2) } | |
format ? pretty_print_address(bin) : bin | |
end | |
def self.mask_for_addresses_required(addresses_needed) | |
puts addresses_needed | |
Math.log(next_power_of_two(addresses_needed), 2).round(0) | |
end | |
private | |
def to_binary(address) | |
if address.include?(".") | |
address.split(".").map { |c| format("%08B", c) }.join | |
else | |
("1" * address.to_i).ljust(32, "0") | |
end | |
end | |
def machine_part(mask = self.mask, ip = self.ip) | |
length = mask.scan(/0+$/).first.size | |
ip.chars.last(length).join | |
end | |
def self.pretty_print_address(addr) | |
addr.gsub(/.{8}(?=.)/, '\0.') | |
end | |
def self.next_power_of_two(i) | |
return 1 if i <= 0 | |
val = i | |
val -= 1 | |
val = (val >> 1) | val | |
val = (val >> 2) | val | |
val = (val >> 4) | val | |
val = (val >> 8) | val | |
val = (val >> 16) | val | |
val = (val >> 32) | val if i.class == Bignum | |
val + 1 | |
end | |
end | |
net = Network.new("192.168.0.255/16") | |
formatted = { format: true } | |
puts "Mask: #{net.mask(formatted)}" | |
puts "IP: #{net.ip(formatted)}" | |
# puts "#{net.available_addresses} addresses" | |
# puts Network.mask_to_binary("/16", formatted) | |
p = Network.mask_for_addresses_required(63) | |
# puts Network.mask_to_binary("/#{32 - p}", formatted) | |
# puts Network.mask_to_decimal("/#{32 - p}", formatted) | |
puts Network.mask_to_binary("/#{32 - p}", formatted).split(".").map { |c| c.to_i(2) }.join(".") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment