Go:将符文(字符串)转换为二进制的字符串表示形式

tho*_*roc 1 string binary type-conversion go

这是为了防止其他人正在学习Golang并且想知道如何从字符串转换为二进制的字符串表示.

长话短说,我一直在寻找标准库而无法找到合适的电话.所以我开始使用类似于以下内容的东西:

func RuneToBinary(r rune) string {
    var buf bytes.Buffer
    b := []int64{128, 64, 32, 16, 8, 4, 2, 1}
    v := int64(r)
    for i := 0; i < len(b); i++ {
        t := v-b[i]
        if t >= 0 {
           fmt.Fprintf(&buf, "1")
           v = t
        } else {
           fmt.Fprintf(&buf, "0")
        }
    }

    return buf.String()
}
Run Code Online (Sandbox Code Playgroud)

这是一个好花花公子,但经过几天的环顾四周,我发现,我应该使用已经fmt包代替,只是格式化rune%b%:

var r rune
fmt.Printf("input: %b ", r)
Run Code Online (Sandbox Code Playgroud)

有一个更好的方法吗?

谢谢

icz*_*cza 6

标准库支持

fmt.Printf("%b", r) - 这个解决方案已经非常紧凑,易于编写和理解.如果您需要结果string,可以使用模拟Sprintf()功能:

s := fmt.Sprintf("%b", r)
Run Code Online (Sandbox Code Playgroud)

您还可以使用strconv.FormatInt()具有多种类型的函数int64(因此您首先必须转换rune)以及可以传递2以获得二进制表示结果的基数:

s := strconv.FormatInt(int64(r), 2)
Run Code Online (Sandbox Code Playgroud)

请注意,在Go rune中只是一个别名int32,两种类型是同一个(只是你可以通过2个名称来引用它).

手动完成("简单但天真"):

如果您想"手动"执行此操作,则可以使用比原始解决方案简单得多的解决方案.您可以使用测试最低位r & 0x01 == 0并移位所有位r >>= 1.只是"循环"所有位并附加"1""0"取决于位:

请注意,这只是为了演示,它在性能方面远远不够理想(生成"冗余" string):

func RuneToBin(r rune) (s string) {
    if r == 0 {
        return "0"
    }
    for digits := []string{"0", "1"}; r > 0; r >>= 1 {
        s = digits[r&1] + s
    }
    return
}
Run Code Online (Sandbox Code Playgroud)

注意:函数不处理负数.如果你还想处理负数,你可以先检查它并继续它的正值并用减号开始返回值'-'.这也适用于下面的其他手动解决方案.

手动性能解决方案:

对于快速解决方案,我们不应附加字符串.由于Go中的字符串只是使用UTF-8编码的字节片段,因此附加数字只是附加符文的字节值'0'或者'1'只是一个字节(不是多个).所以我们可以分配一个足够大的缓冲区/数组(rune32位,最多32位二进制数字),并向后填充,这样我们甚至不必在最后反转它.并返回最后转换为数组的已使用部分string.请注意,我甚至没有调用内置append函数来附加二进制数字,我只是设置了构建结果的数组的相应元素:

func RuneToBinFast(r rune) string {
    if r == 0 {
        return "0"
    }
    b, i := [32]byte{}, 31
    for ; r > 0; r, i = r>>1, i-1 {
        if r&1 == 0 {
            b[i] = '0'
        } else {
            b[i] = '1'
        }
    }
    return string(b[i+1:])
}
Run Code Online (Sandbox Code Playgroud)