假设我的十进制数是9766322441
所以它的对应值是70.30.65.9
但是当这个IP地址IC转换回来时,它会给出一些不同的十进制数1176387849
...当我转换时IP地址pf google.com即64.233.187.99
然后它会给出1089059683
,反向转换会提供正确的IP地址,即64.233.187.99
...
我的问题是上面提到的数字有什么问题?我也尝试9579342332
,但结果相同。它给出了错误的反向转换??
背后的原因是什么?
您可以使用this calculator进行计算。
答案 0 :(得分:18)
您的值不正确70.30.65.9将与1176387849相对应,但从不与9766322441相对应。
#include <iostream.h>
main()
{
// Initialize the variables
unsigned long a,b,c,d,base10IP;
// Get the IP address from user
cout << "\nEnter an IP address in dotted quad notation (x.x.x.x)";
cout << "\nwith each section seperated by a space: ";
cin >> a >> b >> c >> d;
// Do calculations to convert IP to base 10
a *= 16777216;
b *= 65536;
c *= 256;
base10IP = a + b + c + d;
// Output new IP address
cout << "\nThe converted address is: " << base10IP << '\n';
}
/**
* @author Charles Johnson
* from http://www.technojeeves.com/joomla/index.php/free/58-convert-ip-address-to-number
*/
public class IpConverter {
public static void main(String[] args) {
System.out.println(longToIp(Long.valueOf(args[0], 16)));
}
public static String toHex(String ipAddress) {
return Long.toHexString(IpConverter.ipToLong(ipAddress));
}
public static long ipToLong(String ipAddress) {
long result = 0;
String[] atoms = ipAddress.split("\\.");
for (int i = 3; i >= 0; i--) {
result |= (Long.parseLong(atoms[3 - i]) << (i * 8));
}
return result & 0xFFFFFFFF;
}
public static String longToIp(long ip) {
StringBuilder sb = new StringBuilder(15);
for (int i = 0; i < 4; i++) {
sb.insert(0, Long.toString(ip & 0xff));
if (i < 3) {
sb.insert(0, '.');
}
ip >>= 8;
}
return sb.toString();
}
}
String ip="70.30.65.9";
String[] addrArray = ip.split("\.");
long num = 0;
for (int i = 0; i < addrArray.length; i++) {
int power = 3 - i;
num += ((Integer.parseInt(addrArray[i]) % 256 * Math.pow(256, power)));
}
function myip2long($ip) {
if (is_numeric($ip)) {
return sprintf( "%u", floatval($ip) );
} else {
return sprintf( "%u", floatval(ip2long($ip) ));
}
}
尝试应用它,例如:
echo myip2long("192.168.1.1");
function myip2long2($ip){
$d = 0.0;
$b = explode(".", $ip,4);
for ($i = 0; $i < 4; $i++) {
$d *= 256.0;
$d += $b[$i];
};
return $d;
}
这个会为您提供与上面相同的结果:
function customLong2ip($ip){
$b=array(0,0,0,0);
$c = 16777216.0;
$ip += 0.0;
for ($i = 0; $i < 4; $i++) {
$k = (int) ($ip / $c);
$ip -= $c * $k;
$b[$i]= $k;
$c /=256.0;
};
$d=join('.', $b);
return($d);
}
答案 1 :(得分:3)
您的有效IPV4范围超过了十进制值9766322441.如果转换为十六进制,它会为您提供值为0x2461E4109,占用5个八位字节而不是4:
02, 46, 1e, 41, 09
计算器只是截断值为0x02的八位字节,并使用4个最低有效八位字节转换该值。
0x461E4109的计算为您提供了计算器显示的“70.30.65.9”。
如何在Java中执行此操作:
我建议使用标准Java类进行InetAddress操作。这应该适用于IPV4和IPv6:http://docs.oracle.com/javase/1.5.0/docs/api/java/net/InetAddress.html
您可能正在寻找类似的东西(我在10年前使用过Java,所以如果您发现它们,请随时纠正语法错误)
InetAddress Address = InetAddress.getByName("192.168.0.1");
InetAddress Address = InetAddress.getByName(raw2);
String s1 = Address.toString();
byte[] raw = Adress.getAddress();
byte[] rawIPv4 = {192, 168, 0, 1};
InetAddress Address1 = InetAddress.getByName(rawIPV4);
InetAddress Address2 = InetAddress.getByName("2607:f0d0:1002:51::4");
byte[] rawIPV6 = Adress.getAddress();
IPv6示例还涵盖了地址中“压缩零”的情况(51和4之间的“::”)。
无论如何,您可能需要检查这个以将字节数组转换为整数:
Byte Array and Int conversion in Java
但请注意,IPV6格式对单个IP地址使用16个字节,因此我不确定您是否可以使用计算器中显示的单个整数值来表示它。
答案 2 :(得分:2)
IPv4地址是32位。
数字9,766,322,441
无法在32位(最大值:4,294,967,295
)上表示。
答案 3 :(得分:1)
在阅读原帖和随后的帖子以回应人们的回答时,我得到了一个明显的印象,即您原来的“10位小数”实际上是您想要以某种方式变成IP地址的电话号码。
“因为我想开发用于将移动设备转换为ip的算法,反之亦然”
它不起作用。这就像询问如何获取MAC地址并将其转换为IP地址。电话号码和IP地址由两个完全不同的权限分配。没有算法将两者联系起来。
答案 4 :(得分:0)
实际上IP地址可以转换为32位java整数,只是数字可能是负数。这是非常好的,因为你可以来回转换它而不会丢失数据。现在,如果你真的想要使用额外的32位并将其存储在一个很长的位置,那么它对你来说看起来不是负面的,但它的浪费。您可以编写一个函数将其强制转换为未签名但将其存储在int。
中答案 5 :(得分:0)
问题是为什么9766322441转换为70.30.65.9但转换回来时它给出了1176387849而不是9766322441.答案是因为4294967296是IP 256.256.256.256所代表的最高十进制数。
高于4294967296它将在回程中转换为低于256.256.256.256的数字,就像在车上滚动里程表一样。 9766322441显然是4294967296值的两倍多,并且最终在里程表的第三卷上以两次结束时输出里程表1176387849。然后,这个新号码将通常在范围内转换为IP地址和从IP地址转换。
答案 6 :(得分:0)
在Excel中也有一些方法可以做到这一点。一些计算是混乱的,但最简单的是使用用户定义函数,如本文How to Sort IP Address Lists in Excel中所述