以相反顺序转换整数以按相反顺序生成IP

时间:2016-11-10 07:23:10

标签: go ip-address bitwise-operators

我想以相反的顺序生成IP。

生成IP地址的功能如下:

val := 1<<(32-prefixLen) // let take prefixLen as 24
IP4(val) = IP4(256) = 0.0.1.0

我希望IP的顺序相反,即0.1.0.0,因此请以反向字节转换val并将其发送到IP4()函数。

我尝试过的功能导致整数溢出:

temp1:=byte(val*0xff<<24)    
temp2:=byte(val*0xff00<<16)   
temp3:=byte(val*0xff0000<<8)
temp4:=byte(val*0xff000000)  
valReverse := uint32(temp4)|uint32(temp3)|uint32(temp2)|uint32(temp1)
IP4(valReverse)=0.1.0.0 //expected

1 个答案:

答案 0 :(得分:2)

反转字节

首先,您必须使用uint32类型而不是byte,因为byte值只有8位(8位以上的位位置不存在)。

接下来,您必须使用按位AND,&而不是乘法*

第三,班次值不正确。请参阅此工作示例:

prefixLen := uint32(24)

var val uint32
val = 1 << (32 - prefixLen)
fmt.Printf("%08x\n", val)

temp1 := uint32(val & 0xff << 24)
temp2 := uint32(val & 0xff00 << 8)
temp3 := uint32(val & 0xff0000 >> 8)
temp4 := uint32(val & 0xff000000 >> 24)
valReverse := uint32(temp4) | uint32(temp3) | uint32(temp2) | uint32(temp1)

fmt.Printf("%08x\n", valReverse)

输出(在Go Playground上尝试):

00000100
00010000

但我个人只想使用net.IP类型,它使用字节切片对IP地址建模,使用它可以简单地使用切片反转算法反转字节。

这就是它的样子:

ip := net.IPv4(0, 0, 1, 0).To4()
fmt.Println(ip)

// Reverse:
for i, j := 0, len(ip)-1; i < j; i, j = i+1, j-1 {
    ip[i], ip[j] = ip[j], ip[i]
}
fmt.Println(ip)

输出(在Go Playground上尝试):

0.0.1.0
0.1.0.0

注意:如果您将IP设置为uint32的值,您仍然可以使用net.IP类型,创建net.IP值,如下所示:

ip := net.IPv4(byte(val>>24), byte(val>>16), byte(val>>8), byte(val)).To4()

反转位

如果要反转位,则必须逐位进行。一种可能的解决方案是:

prefixLen := uint32(24)

var val uint32
val = 1 << (32 - prefixLen)
fmt.Printf("%08x\n", val)

var valReverse uint32
for i := 0; i < 32; i, val = i+1, val>>1 {
    valReverse = valReverse<<1 | val&0x01
}
fmt.Printf("%08x\n", valReverse)

输出(在Go Playground上尝试):

00000100
00800000

另一种可能更复杂的反转方式:

var valReverse uint32
for mask1, mask2 := uint32(0x01), uint32(0x80000000); mask2 != 0; mask1, mask2 = mask1<<1, mask2>>1 {
    if val&mask1 != 0 {
        valReverse |= mask2
    }
}

输出相同,请在Go Playground上尝试此变体。