আমি এমন একটি ফাংশন খুঁজছি যা একটি স্ট্যান্ডার্ড আইপিভি 4 অ্যাড্রেসকে পূর্ণসংখ্যায় রূপান্তর করবে। বিপরীতে যে কোনও ক্রিয়াকলাপের জন্য বোনাস পয়েন্ট উপলব্ধ।
সমাধান সি # তে হওয়া উচিত।
উত্তর:
32 বিট স্বাক্ষরবিহীন পূর্ণসংখ্যার হয় IPv4- র ঠিকানা। এদিকে, IPAddress.Address
সম্পত্তিটিকে অবমূল্যায়ন করার সময় এমন একটি ইন্টার -64 যা আইপিভি 4 ঠিকানার স্বাক্ষরযুক্ত 32-বিট মানটি দেয় (ক্যাচটি এটি নেটওয়ার্ক বাইট ক্রমে রয়েছে, সুতরাং আপনাকে এটিকে চারপাশে অদলবদল করতে হবে)।
উদাহরণস্বরূপ, আমার স্থানীয় google.com এ রয়েছে 64.233.187.99
। এটি সমান:
64*2^24 + 233*2^16 + 187*2^8 + 99
= 1089059683
এবং প্রকৃতপক্ষে, HTTP: // 1089059683 / প্রত্যাশিত হিসাবে কাজ করে (কমপক্ষে উইন্ডোজে, IE, ফায়ারফক্স এবং ক্রোমের সাথে পরীক্ষিত; যদিও আইফোনে কাজ করে না)।
নেটওয়ার্ক / হোস্ট বাই বাই অদলবদল সহ উভয় রূপান্তর দেখাতে এখানে একটি পরীক্ষা প্রোগ্রাম রয়েছে:
using System;
using System.Net;
class App
{
static long ToInt(string addr)
{
// careful of sign extension: convert to uint first;
// unsigned NetworkToHostOrder ought to be provided.
return (long) (uint) IPAddress.NetworkToHostOrder(
(int) IPAddress.Parse(addr).Address);
}
static string ToAddr(long address)
{
return IPAddress.Parse(address.ToString()).ToString();
// This also works:
// return new IPAddress((uint) IPAddress.HostToNetworkOrder(
// (int) address)).ToString();
}
static void Main()
{
Console.WriteLine(ToInt("64.233.187.99"));
Console.WriteLine(ToAddr(1089059683));
}
}
আইপিভি 4 থেকে সঠিক সংখ্যায় এবং পিছনে রূপান্তর করতে এখানে একজোড়া পদ্ধতির উপায় রয়েছে :
public static uint ConvertFromIpAddressToInteger(string ipAddress)
{
var address = IPAddress.Parse(ipAddress);
byte[] bytes = address.GetAddressBytes();
// flip big-endian(network order) to little-endian
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
return BitConverter.ToUInt32(bytes, 0);
}
public static string ConvertFromIntegerToIpAddress(uint ipAddress)
{
byte[] bytes = BitConverter.GetBytes(ipAddress);
// flip little-endian to big-endian(network order)
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
return new IPAddress(bytes).ToString();
}
উদাহরণ
ConvertFromIpAddressToInteger("255.255.255.254"); // 4294967294
ConvertFromIntegerToIpAddress(4294967294); // 255.255.255.254
ব্যাখ্যা
আইপি অ্যাড্রেসগুলি নেটওয়ার্ক ক্রমে (বিগ-এন্ডিয়ান) থাকে, তবে int
এসগুলি উইন্ডোজটিতে স্বল্প-এন্ডিয়ান হয়, সুতরাং একটি সঠিক মান পেতে, আপনাকে সামান্য-এন্ডিয়ান সিস্টেমে রূপান্তরিত করার আগে বাইটগুলি বিপরীত করতে হবে।
এছাড়াও, এমনকি এর জন্য IPv4
, কোনও ব্রডকাস্টের ঠিকানা থেকে int
বড় ঠিকানা ধরে রাখতে পারে না , সুতরাং একটি ব্যবহার করুন ।127.255.255.255
(255.255.255.255)
uint
1.1.1.1
কারণ এটির বাইট অ্যারে প্যালিনড্রমিক। নন-প্যালিনড্রোমিক 127.0.0.1
বা এর মতো চেষ্টা করুন 192.168.1.1
।
1.1.1.1
, 2.2.2.2
, 123.123.123.123
সবসময় একই ফল। উত্তরসূরীদের
System.Net.IPAddress
এই কাজটি পেতে আমাকে ব্যবহার করতে হয়েছিল তা নোট করতে পছন্দ করুন । দুর্দান্ত কাজ!
2.1.1.2
একই হবে।
@ ব্যারি কেলি এবং @ অ্যান্ড্রু হ্যারে, আসলে, আমি মনে করি না যে এটি করার সবচেয়ে সুস্পষ্ট উপায় (সমস্ত কিছু সঠিক) lying
একটি অন্তর্গত 32 "ফর্ম্যাট" IP ঠিকানা নিম্নলিখিত কাঠামো হিসাবে দেখা যেতে পারে
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IPv4Address
{
public Byte A;
public Byte B;
public Byte C;
public Byte D;
}
// to actually cast it from or to an int32 I think you
// need to reverse the fields due to little endian
সুতরাং আইপি ঠিকানাটি রূপান্তর করতে 64.233.187.99 আপনি করতে পারেন:
(64 = 0x40) << 24 == 0x40000000
(233 = 0xE9) << 16 == 0x00E90000
(187 = 0xBB) << 8 == 0x0000BB00
(99 = 0x63) == 0x00000063
---------- =|
0x40E9BB63
যাতে আপনি তাদের ব্যবহার করে যোগ করতে পারেন + বা আপনি বিনাইন করতে পারেন বা তাদের একসাথে করতে পারেন। 0x40E9BB63 এর ফলাফল যা 1089059683। (আমার মতে হেক্সের দিকে তাকানো এটি বাইটগুলি দেখতে অনেক সহজ)
সুতরাং আপনি এই ফাংশনটি লিখতে পারেন:
int ipToInt(int first, int second,
int third, int fourth)
{
return (first << 24) | (second << 16) | (third << 8) | (fourth);
}
LayoutKind.Explicit
এবং FieldOffset
বাইটগুলি যে ক্রমে সজ্জিত করা হয়েছে তার বিপরীতে। অবশ্যই, এটি কেবল সামান্য এন্ডিয়ান আর্কিটেকচারের জন্য কাজ করে। গিথুবের উপর উদাহরণ ।
int
তাই সাইন করা হয়েছে যদি তোমরা বিট 24 দ্বারা 192 নামান আপনাকে নেতিবাচক পূর্ণসংখ্যা তাই এই কোড উচ্চ অক্টেট প্রথম স্থানে উচ্চ বিট থাকার জন্য নষ্ট হয়ে গেছে পাবেন।
এটি ব্যবহার করে দেখুন:
private int IpToInt32(string ipAddress)
{
return BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(), 0);
}
private string Int32ToIp(int ipAddress)
{
return new IPAddress(BitConverter.GetBytes(ipAddress).Reverse().ToArray()).ToString();
}
Reverse()
অকার্যকর প্রত্যাবর্তন করে, যাতে আপনি ToArray()
এটি (ভবিষ্যতের পাঠকদের জন্য) কল করতে পারবেন না । পরিবর্তে, বিপরীত বাইটগুলিতে একটি মান নির্ধারণ করুন, তারপরে আপনি ToArray () কল করতে পারেন।
যেহেতু নুন কোনও কোড পোস্ট করেছেন যা ব্যবহার করে BitConverter
এবং প্রকৃতপক্ষে চূড়ান্ততা পরীক্ষা করে, এখানে যায়:
byte[] ip = address.Split('.').Select(s => Byte.Parse(s)).ToArray();
if (BitConverter.IsLittleEndian) {
Array.Reverse(ip);
}
int num = BitConverter.ToInt32(ip, 0);
এবং ফিরে:
byte[] ip = BitConverter.GetBytes(num);
if (BitConverter.IsLittleEndian) {
Array.Reverse(ip);
}
string address = String.Join(".", ip.Select(n => n.ToString()));
uint
যদি এমন 32 টি বিট ডেটা স্বাক্ষরযুক্ত নাম্বার হিসাবে চান তবে আপনাকে int
একই তথ্য ব্যবহার করতে হবে। আপনি যদি এটি একটি ডাটাবেসে সংরক্ষণ করতে চান তবে এটি একটি int
আরও উপযুক্ত উপযুক্ত, আপনার bigint
এটি স্বাক্ষরবিহীন আকারে সঞ্চয় করতে সক্ষম হতে হবে।
uint
আপনি এটি এড্রেস বারে টাইপ করতে পারবেন না, আপনাকে প্রথমে এটি করতে পাঠ্য আকারে রূপান্তর করতে হবে। int
পাঠ্য রূপে রূপান্তরকরণের সহজতম ফর্মটি ব্যবহার করে কোনও কার্যকর আইপি ঠিকানা তৈরি করে না কারণ এটি ব্যবহার না করার পক্ষে ভাল যুক্তি নয়।
uint
, এটি একটি এর পাঠ্য উপস্থাপনা uint
।
আমি বর্ণিত সমাধানগুলির সাথে কিছু সমস্যার মুখোমুখি হয়েছি, যখন খুব বড় মূল্যের সাথে আইপি অ্যাড্রেসগুলির মুখোমুখি হয়। ফলাফলটি হ'ল, যে বাইট [0] * 16777216 জিনিসটি উপচে পড়বে এবং নেতিবাচক ইনট মান হয়ে যাবে। এটি আমার জন্য কী ঠিক করেছে, এটি একটি সাধারণ ধরণের কাস্টিং অপারেশন।
public static long ConvertIPToLong(string ipAddress)
{
System.Net.IPAddress ip;
if (System.Net.IPAddress.TryParse(ipAddress, out ip))
{
byte[] bytes = ip.GetAddressBytes();
return
16777216L * bytes[0] +
65536 * bytes[1] +
256 * bytes[2] +
bytes[3]
;
}
else
return 0;
}
ডেভি ল্যান্ডম্যানের ক্রিয়াকলাপের বিপরীত
string IntToIp(int d)
{
int v1 = d & 0xff;
int v2 = (d >> 8) & 0xff;
int v3 = (d >> 16) & 0xff;
int v4 = (d >> 24);
return v4 + "." + v3 + "." + v2 + "." + v1;
}
আমার প্রশ্নটি বন্ধ ছিল, কেন আমি জানি না। এখানে গৃহীত উত্তর আমার প্রয়োজনের মতো নয়।
এটি আমাকে একটি আইপির সঠিক সংখ্যার মান দেয় ..
public double IPAddressToNumber(string IPaddress)
{
int i;
string [] arrDec;
double num = 0;
if (IPaddress == "")
{
return 0;
}
else
{
arrDec = IPaddress.Split('.');
for(i = arrDec.Length - 1; i >= 0 ; i = i -1)
{
num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
}
return num;
}
}
যথাযথ লিটল-এন্ডিয়ান ফর্ম্যাটে UInt32 সহ, এখানে দুটি সাধারণ রূপান্তর ফাংশন রয়েছে:
public uint GetIpAsUInt32(string ipString)
{
IPAddress address = IPAddress.Parse(ipString);
byte[] ipBytes = address.GetAddressBytes();
Array.Reverse(ipBytes);
return BitConverter.ToUInt32(ipBytes, 0);
}
public string GetIpAsString(uint ipVal)
{
byte[] ipBytes = BitConverter.GetBytes(ipVal);
Array.Reverse(ipBytes);
return new IPAddress(ipBytes).ToString();
}
উপরের বেশ কয়েকটি উত্তরকে একটি এক্সটেনশান পদ্ধতিতে জমা দেওয়া হয়েছে যা মেশিনের এন্ডিয়েনসনেস পরিচালনা করে এবং আইপিভি 4 অ্যাড্রেসগুলি পরিচালনা করে যেগুলি আইপিভি 6-এ ম্যাপ করা হয়েছিল।
public static class IPAddressExtensions
{
/// <summary>
/// Converts IPv4 and IPv4 mapped to IPv6 addresses to an unsigned integer.
/// </summary>
/// <param name="address">The address to conver</param>
/// <returns>An unsigned integer that represents an IPv4 address.</returns>
public static uint ToUint(this IPAddress address)
{
if (address.AddressFamily == AddressFamily.InterNetwork || address.IsIPv4MappedToIPv6)
{
var bytes = address.GetAddressBytes();
if (BitConverter.IsLittleEndian)
Array.Reverse(bytes);
return BitConverter.ToUInt32(bytes, 0);
}
throw new ArgumentOutOfRangeException("address", "Address must be IPv4 or IPv4 mapped to IPv6");
}
}
ইউনিট পরীক্ষা:
[TestClass]
public class IPAddressExtensionsTests
{
[TestMethod]
public void SimpleIp1()
{
var ip = IPAddress.Parse("0.0.0.15");
uint expected = GetExpected(0, 0, 0, 15);
Assert.AreEqual(expected, ip.ToUint());
}
[TestMethod]
public void SimpleIp2()
{
var ip = IPAddress.Parse("0.0.1.15");
uint expected = GetExpected(0, 0, 1, 15);
Assert.AreEqual(expected, ip.ToUint());
}
[TestMethod]
public void SimpleIpSix1()
{
var ip = IPAddress.Parse("0.0.0.15").MapToIPv6();
uint expected = GetExpected(0, 0, 0, 15);
Assert.AreEqual(expected, ip.ToUint());
}
[TestMethod]
public void SimpleIpSix2()
{
var ip = IPAddress.Parse("0.0.1.15").MapToIPv6();
uint expected = GetExpected(0, 0, 1, 15);
Assert.AreEqual(expected, ip.ToUint());
}
[TestMethod]
public void HighBits()
{
var ip = IPAddress.Parse("200.12.1.15").MapToIPv6();
uint expected = GetExpected(200, 12, 1, 15);
Assert.AreEqual(expected, ip.ToUint());
}
uint GetExpected(uint a, uint b, uint c, uint d)
{
return
(a * 256u * 256u * 256u) +
(b * 256u * 256u) +
(c * 256u) +
(d);
}
}
আপনি যদি ফাংশনে আগ্রহী হন তবে এখানে উত্তরটি এটি কীভাবে করা হয় তা নয়:
int ipToInt(int first, int second,
int third, int fourth)
{
return Convert.ToInt32((first * Math.Pow(256, 3))
+ (second * Math.Pow(256, 2)) + (third * 256) + fourth);
}
সঙ্গে first
মাধ্যমে fourth
IPv4 ঠিকানা বিভাগগুলি হচ্ছে।
public bool TryParseIPv4Address(string value, out uint result)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(value, out ipAddress) ||
(ipAddress.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork))
{
result = 0;
return false;
}
result = BitConverter.ToUInt32(ipAddress.GetAddressBytes().Reverse().ToArray(), 0);
return true;
}
public static Int32 getLongIPAddress(string ipAddress)
{
return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0));
}
উপরের উদাহরণটি আমি যাব be
আইপিএড্রেস ব্যবহার করার সময় কোনটি প্রয়োজন। পার্স (স্ট্রিং) ফাংশন। দীর্ঘশ্বাস.
আমি আজ কাজ করেছিলাম এমন একটি সমাধান এখানে দেওয়া হয়েছে (প্রথমে গুগল করা উচিত ছিল!):
private static string IpToDecimal2(string ipAddress)
{
// need a shift counter
int shift = 3;
// loop through the octets and compute the decimal version
var octets = ipAddress.Split('.').Select(p => long.Parse(p));
return octets.Aggregate(0L, (total, octet) => (total + (octet << (shift-- * 8)))).ToString();
}
আমি লিনিকিউ, ল্যাম্বদা এবং জেনেরিকের কিছু এক্সটেনশন ব্যবহার করছি, সুতরাং এটি একই ফলাফল তৈরি করার সময় এটি কিছু নতুন ভাষার বৈশিষ্ট্য ব্যবহার করে এবং আপনি কোডের তিনটি লাইনে এটি করতে পারেন।
আপনার আগ্রহী হলে আমার ব্লগে আমার কাছে ব্যাখ্যা আছে।
চিয়ার্স, -জেসি
আমি মনে করি এটি ভুল: "65536" ==> 0.0.255.255 "হওয়া উচিত:" 65535 "==> 0.0.255.255" বা "65536" ==> 0.1.0.0 "
@ ডেভি ল্যাডম্যান আপনার শিফট সহ সমাধানটি তাত্পর্যপূর্ণ তবে কেবল কম বা সমান 99 নম্বর দিয়ে শুরু হওয়া আইপি এর জন্য ইনফ্যাক্ট প্রথম অষ্টেক্টটি দীর্ঘকাল অবধি আপ করতে হবে।
যাইহোক দীর্ঘ সময়ের সাথে ফিরে রূপান্তর করা বেশ কঠিন কারণ 64৪ বিট (আইপি-র জন্য 32 নয়) সংরক্ষণ করুন এবং 4 বাইট জিরো দিয়ে পূরণ করুন
static uint ToInt(string addr)
{
return BitConverter.ToUInt32(IPAddress.Parse(addr).GetAddressBytes(), 0);
}
static string ToAddr(uint address)
{
return new IPAddress(address).ToString();
}
উপভোগ করুন!
ম্যাসিমো
ধরে নিলাম স্ট্রিং ফর্ম্যাটে আপনার একটি আইপি ঠিকানা রয়েছে (যেমন 254.254.254.254)
string[] vals = inVal.Split('.');
uint output = 0;
for (byte i = 0; i < vals.Length; i++) output += (uint)(byte.Parse(vals[i]) << 8 * (vals.GetUpperBound(0) - i));
var address = IPAddress.Parse("10.0.11.174").GetAddressBytes();
long m_Address = ((address[3] << 24 | address[2] << 16 | address[1] << 8 | address[0]) & 0x0FFFFFFFF);
আমি লক্ষ্য করেছি যে System.Net.IPAddress এর ঠিকানা ঠিকানা (System.Int64) এবং কনস্ট্রাক্টর রয়েছে, যা Int64 ডেটা টাইপ গ্রহণ করে। সুতরাং আপনি এটি আইপি ঠিকানাটিকে / থেকে সংখ্যায় রূপান্তর করতে (যদিও Int32 নয়, তবে Int64 নয়) ফর্ম্যাট করতে পারেন।
int
বেশিরভাগ সিস্টেমে গুলি সামান্য এন্ডিয়ান রয়েছে। সুতরাং রূপান্তর করার আগে আপনাকে অবশ্যই বাইটগুলি বিপরীত করতে হবে। সঠিক রূপান্তরগুলির জন্য আমার উত্তর দেখুন । এছাড়াও, এমনকি আইপিভি 4-র জন্যও কোনওint
ঠিকানা থেকে বড় ঠিকানা ধরে রাখতে পারে না127.255.255.255
, যেমন সম্প্রচারের ঠিকানা, সুতরাং একটি ব্যবহার করুনuint
।