英文:
How do I get the bits from a byte in golang?
问题
我正在尝试计算两个字节之间的汉明距离,例如
HammingDist(byte(255), byte(0)) == 8
我需要获取每个字节中的位,但是我在任何内置包中都找不到相应的函数。所以,给定 byte(1)
,我该如何获取其位表示 00000001?
英文:
I'm trying to compute the Hamming distance between two byte's, such that
HammingDist(byte(255), byte(0)) == 8
I need the bits in each byte, but I can't find any function in any of the built-in packages for doing so. So, given byte(1)
how do I get the bit representation 00000001?
答案1
得分: 27
你可以使用fmt.Sprintf(%08b, ..)
来查看位的可视化表示,正如其他人已经建议的那样。
然而,如果你想在操作中使用这些位,比如计算汉明距离,你需要使用位运算符。
要计算字节的第n位,你需要将该字节与另一个字节进行位与
操作,该字节的第n位设置为1,其余位设置为0(也称为掩码)。换句话说,另一个字节(掩码)就是数字2^n-1。
例如,要找到数字13(00001101)的第1位,我们需要将其与2^0 = 1(00000001)进行掩码操作。我们比较对这两个数字进行位与操作的输出与掩码的结果。如果它们相等,说明第n位为1,否则为0。我们继续这样进行,找到所有的位。以下是用Go代码示例说明:
fmt.Print(13 & 1) // 输出: 1 -> 1
fmt.Print(13 & 2) // 输出: 2 -> 0
fmt.Print(13 & 4) // 输出: 4 -> 1
fmt.Print(13 & 8) // 输出: 8 -> 1
// 不必继续,但为了示例的完整性而显示
fmt.Print(13 & 16) // 输出: 0 -> 0
fmt.Print(13 & 32) // 输出: 0 -> 0
fmt.Print(13 & 64) // 输出: 0 -> 0
fmt.Print(13 & 128) // 输出: 0 -> 0
因此,13的二进制表示为00001101。
这是我最近编写的一个用于计算两个字节数组之间汉明距离的函数。在你的情况下,只需传递一个由单个字节组成的数组即可。
func hamming(a, b []byte) (int, error) {
if len(a) != len(b) {
return 0, errors.New("a b are not the same length")
}
diff := 0
for i := 0; i < len(a); i++ {
b1 := a[i]
b2 := b[i]
for j := 0; j < 8; j++ {
mask := byte(1 << uint(j))
if (b1 & mask) != (b2 & mask) {
diff++
}
}
}
return diff, nil
}
Go Playground: https://play.golang.org/p/O1EGdzDYAn
英文:
You can see the visual representation of bits using fmt.Sprintf(%08b, ..)
as others have already suggested.
However, if you want to use the bits in operations, such as for calculating the Hamming distance, you'll need to use bitwise operators.
To calculate the nth bit of a byte, you'll need to bitwise AND
that byte with another byte whose nth bit is set to 1 and the rest to 0 (aka masking). In other words, that other byte (mask) is the number 2^n-1.
For example, to find the 1st bit of the number 13 (00001101), we would have to mask it with 2^0 = 1 (00000001). We compare the output of performing bitwise AND on both numbers to the mask. If they are equal, it means that the nth bit is 1, otherwise it is 0. We continue like this and find all the bits. Illustrated in Go code:
fmt.Print(13 & 1) // Output: 1 -> 1
fmt.Print(13 & 2) // Output: 2 -> 0
fmt.Print(13 & 4) // Output: 4 -> 1
fmt.Print(13 & 8) // Output: 8 -> 1
// Not necessary to continue, but shown for the sake of the example
fmt.Print(13 & 16) // Output: 0 -> 0
fmt.Print(13 & 32) // Output: 0 -> 0
fmt.Print(13 & 64) // Output: 0 -> 0
fmt.Print(13 & 128) // Output: 0 -> 0
Therefore, 13 in binary is 00001101
Here's a function I wrote recently for calculating the Hamming distance between two arrays of bytes. Just pass an array consisting of a single byte each in your case
func hamming(a, b []byte) (int, error) {
if len(a) != len(b) {
return 0, errors.New("a b are not the same length")
}
diff := 0
for i := 0; i < len(a); i++ {
b1 := a[i]
b2 := b[i]
for j := 0; j < 8; j++ {
mask := byte(1 << uint(j))
if (b1 & mask) != (b2 & mask) {
diff++
}
}
}
return diff, nil
}
Go Playground: https://play.golang.org/p/O1EGdzDYAn
答案2
得分: 7
fmt.Sprintf("%08b", byte(1)) 是一个很好的想法。它展示了数字在内部的存储方式。下面是一个计算汉明距离(非常无聊)的示例代码:
package main
import (
"fmt"
)
func HamDist(n1,n2 uint8) uint8 {
var w uint8 = 0
for i := uint8(0); i < 8; i++ {
if n1&(1<<i) != n2&(1<<i) {
w++
}
}
return w
}
func main() {
fmt.Println(HamDist(255,0))
}
现在给你一些任务:
- 使用循环重写代码。
- 扩展程序以计算16位数字的汉明距离。
- 请思考异或运算符的作用,以及如果定义一个计算汉明重量的函数是否可以更容易地计算汉明距离。
英文:
fmt.Sprintf("%08b", byte(1)) is great idea. It shows you, how the number is store internally. And example to compute hamming distance (very boring) could be:
package main
import (
"fmt"
)
func HamDist(n1,n2 uint8) uint8 {
var w uint8 = 0
if n1&1 != n2&1 {
w++
}
if n1&2 != n2&2 {
w++
}
if n1&4 != n2&4 {
w++
}
if n1&8 != n2&8 {
w++
}
if n1&16 != n2&16 {
w++
}
if n1&32 != n2&32 {
w++
}
if n1&64 != n2&64 {
w++
}
if n1&128 != n2&128 {
w++
}
return w
}
func main() {
fmt.Println(HamDist(255,0))
}
And now tasks for you:
- rewrite the code using a loop
- extend program to compute hamming distance of 16-bit number
- please think what xor operator does and whether should not be possible compute HammingDistance easier, if you has defined a function that computes Hamming weight.
答案3
得分: 4
import "math/bits"
bits.OnesCount8(byte(0) ^ byte(255))
import "math/bits"
bits.OnesCount8(byte(0) ^ byte(255))
这段代码是用来计算两个字节之间的异或操作结果中包含的1的个数。具体来说,它将0和255转换为字节类型,然后执行异或操作,最后使用bits.OnesCount8
函数计算结果中包含的1的个数。
英文:
import "math/bits"
bits.OnesCount8(byte(0) ^ byte(255))
答案4
得分: 3
你可以简单地使用以下代码:
fmt.Printf("%08b", YourNumber)
你也可以使用%016b
或%032b
或其他格式。
英文:
You can simply do:
fmt.Printf("%08b", YourNumber)
You can also use %016b
or %032b
or any other.
答案5
得分: 0
这里有一些很好的答案,但计算两个字节之间的汉明距离的另一种方法是对它们进行异或运算,并计算1的数量(权重)。我知道的最简单的计算1的数量的方法是通过使用1进行掩码,并进行右移操作。
这是我在Go语言中编写的一个计算两个字符串之间汉明距离的函数。
func HammingDistance(s1, s2 string) (int, error) {
if len(s1) != len(s2) {
return 0, fmt.Errorf("字符串长度不同,无法计算汉明距离:%d 和 %d", len(s1), len(s2))
}
b1 := []byte(s1)
b2 := []byte(s2)
distance := 0
for i := range b1 {
xored := b1[i] ^ b2[i]
for j := 0; j < 8; j++ {
distance += int(xored & 1)
xored = xored >> 1
}
}
return distance, nil
}
要计算两个字节的汉明距离,你只需要内部的for循环。
英文:
There's been some great answers here, but another way to calculate the Hamming distance between two bytes is to XOR them and count the number of 1s (the weight). The easiest way to count the 1s that I know of is to get the last bit, by masking it with a 1, and then shift right.
Here's a function I wrote in golang to calculate the Hamming distance between two strings.
func HammingDistance(s1, s2 string) (int, error) {
if len(s1) != len(s2) {
return 0, fmt.Errorf("Hamming distance of strings of different lengths %d and %d", len(s1), len(s2))
}
b1 := []byte(s1)
b2 := []byte(s2)
distance := 0
for i := range b1 {
xored := b1[i] ^ b2[i]
for j := 0; j < 8; j++ {
distance += int(xored & 1)
xored = xored >> 1
}
}
return distance, nil
}
To calculate the Hamming distance of two bytes, you would only need the inner for loop.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论