ما هو أبسط طريقة لإضافة واحد إلى سلسلة ثنائية في بيرل؟
سؤال
ولدي المتغير الذي يحتوي على 4 بايت، شبكة النظام عنوان IPv4 (تم إنشاء هذا باستخدام حزمة وتمثيل عدد صحيح). لدي متغير آخر، وهو أيضا 4 بايت شبكة النظام، والشبكة الفرعية. أحاول أن أضيف بعضهم البعض، وإضافة واحد للحصول على أول IP في الشبكة الفرعية.
لتحصل على تمثيل ASCII، يمكنني القيام به inet_ntoa($ip&$netmask)
للحصول على العنوان الأساسي، ولكن هذا خطأ للقيام inet_ntoa((($ip&$netmask)+1)
. أحصل على رسالة مثل:
Argument "\n\r&\0" isn't numeric in addition (+) at test.pm line 95.
وهكذا ما يحدث، وأفضل ما أستطيع أن أقول، وانها تبحث في 4 بايت، ورؤية أن وحدات البايت 4 لا تمثل سلسلة رقمية، ومن ثم رفض إضافة 1.
وهناك طريقة أخرى لوضعه: ما أريد القيام به هو إضافة 1 إلى البايت على الأقل الهامة، التي ما أعرفه هو البايت 4TH؟ وهذا هو، أريد أن تأخذ \n\r&\0
سلسلة وينتهي مع \n\r&\1
السلسلة. ما هو أبسط طريقة للقيام بذلك؟
هل هناك طريقة للقيام بذلك دون الحاجة إلى تفريغ وإعادة تعبئة المتغير؟
المحلول
ما يحدث هو أن تقوم بإجراء سلسلة بايت مع $ip&$netmask
، ومن ثم محاولة التعامل معها كرقم. هذا ليس الذهاب إلى العمل، على هذا النحو. ما لديك لإطعام inet_ntoa
هو.
pack("N", unpack("N", $ip&$netmask) + 1)
وأنا لا أعتقد أن هناك طريقة أسهل للقيام بذلك.
نصائح أخرى
والأعداد الصحيحة مربكة والسلاسل. ولعل البرمجية التالية ستساعد:
use Socket;
$ip = pack("C4", 192,168,250,66); # why not inet_aton("192.168.250.66")
$netmask = pack("C4", 255,255,255,0);
$ipi = unpack("N", $ip);
$netmaski = unpack("N", $netmask);
$ip1 = pack("N", ($ipi&$netmaski)+1);
print inet_ntoa($ip1), "\n";
ما النواتج:
192.168.250.1