我似乎无法将1s和0s的字符串转换为字节数组。
这是我到目前为止的代码:
package main
import (
"fmt"
"strconv"
)
func main() {
/* goal: convert a bit string (ex "10110110") to a byte array */
bitString := "00000000000000000000000100111000100001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011"
myBytes := make([]byte, 16)
for len(bitString) > 7 {
currentByteStr := bitString[:8]
bitString = bitString[8:]
currentByteInt, _ := strconv.ParseUint(currentByteStr, 2, 8)
currentByte := byte(currentByteInt)
myBytes = append(myBytes, currentByte)
}
fmt.Println(myBytes)
}
我显然遗漏了一些东西,但我似乎无法将该大小的字符串转换为字节数组。
编辑我收到了第一个错误:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 56 134 0 0 0 0 0 0 0 0 0 0 3]
但它没有输出我期望的字节数组的样子:
{{1}}
我原以为它是十六进制?那不是golang中字节数组的样子吗?
答案 0 :(得分:2)
我会选择创建一个新类型butString,其中包含转换为[]字节和[]字符串的方法(如果您愿意,可以使用hex)。这也应该防止输入字符串不能被8整除。
package main
import (
"encoding/hex"
"fmt"
"strconv"
)
type bitString string
func (b bitString) AsByteSlice() []byte {
var out []byte
var str string
for i := len(b); i > 0; i -= 8 {
if i-8 < 0 {
str = string(b[0:i])
} else {
str = string(b[i-8 : i])
}
v, err := strconv.ParseUint(str, 2, 8)
if err != nil {
panic(err)
}
out = append([]byte{byte(v)}, out...)
}
return out
}
func (b bitString) AsHexSlice() []string {
var out []string
byteSlice := b.AsByteSlice()
for _, b := range byteSlice {
out = append(out, "0x" + hex.EncodeToString([]byte{b}))
}
return out
}
func main() {
x := bitString("00000000000000000000000100111000100001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011")
fmt.Println(x.AsByteSlice())
fmt.Println(x.AsHexSlice())
}
<强>输出强>
[64 0 1 56 134 0 0 0 0 0 0 0 0 0 0 3]
[0x00 0x00 0x01 0x38 0x86 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03]
如果速度是一个问题,那么可以通过分配具有适当容量的切片并自己跟踪索引来实现优化。
答案 1 :(得分:1)
我认为在这个非常明确的任务的情况下,最好只用手构建数组。
func main() {
/* goal: convert a bit string (ex "10110110") to a byte array */
bitString := "00000000000000000000000100111000100001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011"
lenB := len(bitString) / 8 + 1
bs:=make([]byte,lenB)
count,i := 0,0
var now byte
for _,v:=range bitString {
if count == 8 {
bs[i]=now
i++
now,count = 0,0
}
now = now << 1 + byte(v-'0')
count++
}
if count!=0 {
bs[i]=now << (8-byte(count))
i++
}
bs=bs[:i:i]
fmt.Println(bs)
}
代码使用count
来计算自上次&#34; flush&#34;以来消耗的数字位数。和&#34;冲洗&#34;当有8.变量i
保留字节区域的信息时,循环后可能会有最终的刷新。
byte(v-'0')
是从符文转换为一点。
答案 2 :(得分:0)
这是一个简单的解决方案。
package main
import (
"errors"
"fmt"
)
var ErrRange = errors.New("value out of range")
func bitStringToBytes(s string) ([]byte, error) {
b := make([]byte, (len(s)+(8-1))/8)
for i := 0; i < len(s); i++ {
c := s[i]
if c < '0' || c > '1' {
return nil, ErrRange
}
b[i>>3] |= (c - '0') << uint(7-i&7)
}
return b, nil
}
func main() {
s := "00000000000000000000000100111000100001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000011"
b, err := bitStringToBytes(s)
if err != nil {
fmt.Println(s, err)
}
fmt.Println(b)
fmt.Printf("%b\n", b)
fmt.Printf("%x\n", b)
}
游乐场:https://play.golang.org/p/Ils1gzkY4Dg
输出:
[0 0 1 56 134 0 0 0 0 0 0 0 0 0 0 3]
[0 0 1 111000 10000110 0 0 0 0 0 0 0 0 0 0 11]
00000138860000000000000000000003
注意:已更新@leaf bebop的优化。