2013-01-24 119 views
4

我在SQLSERVER 2008數據庫上存儲IPV4地址爲二進制(4)。所以,我在數據輸入之前轉換了這些值(並且由於公司的限制,我不能在db中創建函數,以及不需要討論的內容)。將IP轉換爲字節/轉換回字符串

public static byte[] IpToBin(string ip) 
{ 
    return IPAddress.Parse(ip).GetAddressBytes(); 
} 

public static string HexToIp(string ip) 
{ 
    return new IPAddress(long.Parse(ip, NumberStyles.HexNumber)).ToString(); 
} 

調用IpToBin後,生成的數據是(例如0x59FC09F3)。當我打電話給HexToIp的IP轉換可能是由於小/大端轉換。

任何人都可以請一個體面的解決方案沒有500億行代碼?

+0

你如何存儲在4個字節的IPv6地址? – dtb

+0

僅限於IPV4 – Alexandre

+1

您在2013年編寫的新代碼不支持IPv6?這就像在1999年編寫新代碼一樣,只支持兩位數字的日期。 [Y2K](http://en.wikipedia.org/wiki/Year_2000_problem) – dtb

回答

6

我認爲這裏真正的問題是,你將原始形式視爲字符串;特別是因爲它是binary(4),你不應該這樣做:只需從數據庫中取回它作爲byte[]IpToBin是好的,但HexToIp大概應該是:

public static IPAddress BinToIp(byte[] bin) 
{ 
    return new IPAddress(bin); 
} 

則:完成任務。但是,與您現有的HexToIp的代碼,你想:

return new IPAddress(new byte[] { 
    Convert.ToByte(ip.Substring(0,2), 16), Convert.ToByte(ip.Substring(2,2), 16), 
    Convert.ToByte(ip.Substring(4,2), 16), Convert.ToByte(ip.Substring(6,2), 16)} 
    ).ToString(); 
+0

實際上,如果我從數據庫中返回字節數組,我deffinitly應該按照你的指導原則,不使用原始十六進制本身,但字節[]。謝謝! – Alexandre

0
public List<IPAddress> SubtractTwoIpAddresses(IPAddress a, IPAddress b, bool includeLeft = true, bool includeRight = true) 
    { 
     List<IPAddress> rv = new List<IPAddress>(); 
     int ipA = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(a.ToString()).GetAddressBytes(), 0)), 
      ipB = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(b.ToString()).GetAddressBytes(), 0)); 
     if (includeLeft) 
      rv.Add(new IPAddress(BitConverter.GetBytes(Math.Min(ipA, ipB)).Reverse().ToArray())); 
     for (int i = 1; i < Math.Max(ipA, ipB) - Math.Min(ipA, ipB); i++) 
      rv.Add(new IPAddress(BitConverter.GetBytes(Math.Min(ipA, ipB) + i).Reverse().ToArray())); 
     if (includeRight) 
      rv.Add(new IPAddress(BitConverter.GetBytes(Math.Max(ipA, ipB)).Reverse().ToArray())); 
     return rv; 
    }