簡體   English   中英

在Go中將十六進制數轉換為二進制數並能夠訪問每一位

[英]Convert a hexadecimal number to binary in Go and be able to access each bit

我目前正在擺弄 Go 並偶然發現了一個問題,我想獲得一些反饋和幫助:)

我的問題是我有一個包含十六進制值的字符串作為輸入,例如:

"60A100"

現在,我想將其轉換為數字的二進制表示,並能夠查看其中的特定位。

我現在對此的解決方案是:

i, err := strconv.ParseUint(rawHex, 16, 32)
if err != nil {
    fmt.Printf("%s", err)
}

// Convert int to binary representation
// %024b indicates base 2, padding with 0, with 24 characters.
bin := fmt.Sprintf("%024b", i)

變量 bin 現在正好包含我想要的內容,除了它是一個我認為不是最佳的字符串。 我寧願我可以有一個單個位的數組,這樣我就可以選擇索引i來獲取位號i :)

因為據我現在所知,如果我像這樣查找索引 8; bin[8],我將得到一個對應於二進制數的十進制數,在 ASCII 表中。

我已經搜索了很多,但我找不到一個完美的解決方案,但也許我找錯了地方。

我希望你們能在這種情況下指導我找到正確/最佳的解決方案:)

提前致謝!

解析值后,您可以直接訪問每個位。 您可以使用如下形式:

func getNthBit(val, n uint32) int {
    n = 32 - n
    if 1 << n & val > 0 {
        return 1
    }
    return 0
}

您可以將其變成代表位的切片

// This could also return []bool
func asBits(val uint64) []uint64 {
    bits := []uint64{}
    for i := 0; i < 24; i++ {
        bits = append([]uint64{val & 0x1}, bits...)
        // or
        // bits = append(bits, val & 0x1)
        // depending on the order you want
        val = val >> 1
    }
    return bits
}

func main() {
    rawHex := "60A100"
    i, err := strconv.ParseUint(rawHex, 16, 32)
    if err != nil {
        fmt.Printf("%s", err)
    }
    fmt.Printf("%024b\n", i)

    fmt.Println(asBits(i))

}

OUTPUT

011000001010000100000000
[0 1 1 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0]

https://play.golang.org/p/KK_AUPgbZu

正如@jimb指出的那樣,您也可以只檢查單個位

fmt.Printf("9th bit is set? %t\n", (i >> 8) & 1 == 1)

這就是@ n-carter的答案。

按照@n-carter 的回答,您可以單獨訪問每一位

有兩種方法:

選項 1:移動value

移倉室號向右n possitions獲得第n個位的第一個。 然后用 1 屏蔽它

func getNthBit(val, n uint32) int {
    // 1. reverse the golang endian
    nthBit := 32-n
    // 2. move the nth bit to the first position
    movedVal := val >> nthBit
    // 3. mask the value, selecting only this first bit
    maskedValue := movedVal & 1
    return maskedValue
    // can be shortened like so
    // return (val >> (32-n)) & 1
}

解釋:

1. Get the right bit index according to the endian
01100000101000010000000001000101
  ^
(32-3)=29nth bit

2. Shift the bits to get n-th in the first possition
01100000101000010000000001000101 >> 29
^^^
00000000000000000000000000000011
                             ^^^

3. Mask first bit. This picks(extracts) the value from this bit
00000000000000000000000000000011
&                              ^
00000000000000000000000000000001
                               1

選項 2:移動 1 並用它進行掩蔽

這可以通過@n-carter 的方式完成。 向左移動 1

func getNthBit(val, n uint32) int {
    // 1. reverse the golang endian
    nthBit := 32-n
    // 2. move the mask 1 bit to the nth position
    mask := 1 << nthBit
    // 3. mask the value, selecting only this nth bit
    maskedValue := val & mask
    if maskedValue == 0 {
        return 0
    }
    return 1
    // can be written shorter like:
    //if val & (1 << (32-n)) == 0 {
    //    return 0
    //}
    //return 1

}

解釋:

1. Get the right bit index according to the endian
01100000101000010000000001000101
  ^
(32-3)=29nth bit

2. Shift the 1 to the n-th position (1 << 29 == 2^(29-1))
00000000000000000000000000000001 << 29
00100000000000000000000000000000

3. Mask n-th bit. This picks(extracts) the value from this bit
01100000101000010000000001000101
&
00100000000000000000000000000000
  1

希望這可以幫助。 在您的腦海中想象位操作需要一些時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM