سؤال

لقد تم استخدام عنوان ip جوهرة و لا يبدو أن لديها القدرة على تحويل من قناع الشبكة من شكل

255.255.255.0 

في شكل CIDR

/24

هل لدى أحد فكرة عن كيفية تحويل بسرعة السابق أن هذا الأخير ؟

هل كانت مفيدة؟

المحلول

وهنا هو طريقة سريعة وقذرة

require 'ipaddr'
puts IPAddr.new("255.255.255.0").to_i.to_s(2).count("1")

ويجب أن يكون هناك وظيفة مناسبة لذلك، لم أجد ذلك، لذلك أنا فقط الاعتماد "1"

إذا كنت تريد الذهاب ليكون باستخدام وظيفة في عدد من الأماكن ولا مانع monkeypatching، وهذا يمكن أن يساعد:

IPAddr.class_eval
  def to_cidr
    "/" + self.to_i.to_s(2).count("1")
  end
end

وبعد ذلك تحصل

IPAddr.new('255.255.255.0').to_cidr
# => "/24"

نصائح أخرى

وكما أن لمعلوماتك، والحفاظ على معلومات يمكن الوصول إليها بسهولة لأولئك الذين يبحثون ...

وإليك طريقة بسيطة لتحويل من CIDR إلى قناع الشبكة الشكل:

def cidr_to_netmask(cidr)
  IPAddr.new('255.255.255.255').mask(cidr).to_s
end

وعلى سبيل المثال:

cidr_to_netmask(24) #=> "255.255.255.0"
cidr_to_netmask(32) #=> "255.255.255.255"
cidr_to_netmask(16) #=> "255.255.0.0"
cidr_to_netmask(22) #=> "255.255.252.0"

وهنا نهجا أكثر الرياضية، وتجنب سلاسل بأي ثمن:

def cidr_mask
    Integer(32-Math.log2((IPAddr.new(mask,Socket::AF_INET).to_i^0xffffffff)+1))
end

ومع "قناع" يجري سلسلة مثل 255.255.255.0. يمكنك تعديله وتغيير الوسيطة الأولى إلى مجرد "قناع" لو "قناع" هو بالفعل تمثيل عدد صحيح من عنوان IP.

وهكذا على سبيل المثال، إذا كان القناع "255.255.255.0"، IPAddr.new (قناع، المقبس :: AF_INET) .to_i سيصبح 0xffffff00، وهو بعد ذلك xor'd مع 0xffffffff، والذي يساوي 255.

ونضيف 1 إلى أن لجعلها مجموعة كاملة من 256 المضيفين، ثم العثور على قاعدة سجل 2 من 256، أي ما يعادل 8 (البتات المستخدمة في عنوان المضيف)، ثم طرح أن 8 من 32، أي ما يعادل 24 (البتات المستخدمة لعنوان الشبكة).

ونحن بعد ذلك يلقي على عدد صحيح لأن Math.log2 إرجاع تعويم.

وتحويل سريع وقذرة:

و"255.255.255.0".split(".").map { |e| e.to_i.to_s(2).rjust(8, "0") }.join.count("1").split(".")

و=> I تقسيم القناع في صفيف

و.map { |e| e.to_i.to_s(2).rjust(8, "0") }

و=> لكل عنصر في صفيف:

و.to_i

و=> تحويل إلى عدد صحيح

و.to_s(2)

و=> تحويل عدد صحيح إلى ثنائي

و.rjust(8, "0")

و=> إضافة الحشو

و=> خريطة إرجاع صفيف مع نفس أصل

و.join

و=> تحويل صفيف إلى سلسلة كاملة

و.count("1")

و=> عدد "1" شخصيات => إعطاء قناع CIDR

    def mask_2_ciddr mask
      "/" + mask.split(".").map { |e| e.to_i.to_s(2).rjust(8, "0") }.join.count("1").to_s
    end

    mask_2_ciddr "255.255.255.0"
    => "/24"
    mask_2_ciddr "255.255.255.128"
    => "/25"

إذا كنت لا تحتاج إلى استخدام عنوان IP الأحجار الكريمة، يمكنك القيام بذلك مع netaddr جوهرة

require 'netaddr'

def to_cidr_mask(dotted_mask)
  NetAddr::CIDR.create('0.0.0.0/'+dotted_mask).netmask
end

to_cidr_mask("255.224.0.0") # => "/11" 
require 'ipaddr'

def serialize_ipaddr(address)
  mask = address.instance_variable_get(:@mask_addr).to_s(2).count('1')
  "#{address}/#{mask}"
end

serialize_ipaddr(IPAddr.new('192.168.0.1/24')) # => "192.168.0.0/24"

قانون يحقق اخفاء طريق الوصول إلى القطاع الخاص سبيل المثال متغير *@mask_addr) من IPAddr سبيل المثال (العنوان ، مرت في serialize_ipaddr).ليست هذه هي الطريقة الموصى بها (حسب المتغيرات سبيل المثال ليست جزءا من فصول العام API ولكن هنا انها افضل من تحليل سلسلة من #فحص في رأيي.

وبالتالي فإن العملية هي على النحو التالي:

  1. على سبيل المثال متغير @mask_addr الذي يمثل قناع الشبكة
  2. الحصول على تمثيل ثنائي مثلا 255.255.255.0 -> 4294967040 -> 11111111111111111111111100000000
  3. عد من 1-s في القاعدة-2 عدد الحصول على CIDR قناع (24)
  4. تشكل سلسلة تتكون عنوان & قناع

تحرير:وأضاف شرح التنفيذ حسب طلب NathanOliver

وهنا هو طريقة للقيام بذلك دون جوهرة IPAddr

(('1'*cidr)+('0'*(32-cidr))).scan(/.{8}/m).map{|e|e.to_i(2)}.join('.')
scroll top