当按位不做时,得到很多ffffffff。如何正确做?

    space := "    "
    str := "12345678999298765432179.170.184.81"

    sp := len(str) % 4
    if sp > 0 {
        str = str + space[0:4-sp]
    }
    fmt.Println(str, len(str))

    hx := hex.EncodeToString([]byte(str))
    ln := len(hx)
    a, _ := strconv.ParseUint(hx[0:8], 16, 0)
    for i := 8; i < ln; i += 8 {
        b, _ := strconv.ParseUint(hx[i:i+8], 16, 0)
        a = a ^ b
    }

    xh := strconv.FormatUint(^a, 16)
    fmt.Println(xh)

输出
ffffffffc7c7dbcb

我只需要
c7c7dbcb

最佳答案

您会得到很多开头的ff,因为您的a号实际上只有32位的“大”,但在“内部”使用了64位的uint64值。 (您正在处理的数字具有8个十六进制数字= 4个字节的数据= 32位。)它有4个前导0字节,如果取反,它将变成ff。您可以使用以下方法进行验证:

fmt.Printf("a %#x\n",a)

输出:
a 0x38382434

要摆脱那些领先的ff,请将结果转换为uint32:
xh := strconv.FormatUint(uint64(uint32(^a)), 16)
fmt.Println(xh)

(转换回uint64是因为 strconv.FormatUint() 期望/需要uint64。)

输出:
c7c7dbcb

另一种选择是应用0xffffffff位掩码:
xh = strconv.FormatUint(^a&0xffffffff, 16)
fmt.Println(xh)

还要注意,您可以使用 fmt.Printf() (如果需要将其作为fmt.Sprintf(),则使用 string )进行打印,在其中指定%08x动词,如果输入的3个前导0位数以上,该动词还将添加前导零(因此strconv.FormatUint()不会添加前导十六进制零) ):
fmt.Printf("%08x", uint32(^a))

这输出相同。尝试在Go Playground上的示例。

关于go - 按位不要没有ffffffff怎么办,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59544360/

10-09 15:18