【问题标题】:Convert int to bytes with variable byte length将 int 转换为具有可变字节长度的字节
【发布时间】:2020-08-31 02:56:13
【问题描述】:

Python 提供了在将整数转换为字节表示时指定字节的长度,即

base64.b64encode((128).to_bytes(1,'little'))
-> b'gA==   

在 Go 中尝试相同的操作时,使用 binary/encode 包,我可以从 uint16 开始,它会给出这样的结果:

buf := make([]byte, 4)
binary.LittleEndian.PutUint16(buf, uint16(128))                                                                                                                                                                
encoded := base64.URLEncoding.EncodeToString(buf)
-> gAAAAA==

或使用PutUvarint

buf := make([]byte, binary.MaxVarintLen64)
n := binary.PutUvarint(buf, num)
b := buf[:n]
encoded := base64.URLEncoding.EncodeToString(b)
-> gAE==

由于编码方式允许在事先不知道长度的情况下进行解码,因此最终得到了更长的编码,这是我不感兴趣的。

那么我可以通过什么方式将 Python 代码翻译成 Go?对于 1 个字节,我可以只使用 byte(num),最多使用 num = 255,但它上面是什么?我怎么从那里去?我想我也可以使用uint64 并截断 最终得到更长的编码 哪个最终得到更长的编码和填充字符?

【问题讨论】:

  • 使用byte order方法名指定编码的长度:2:PutUint16、4:PutUint32、8:PutUint64。如问题所述,使用byte(n) 进行单字节编码。
  • @MuffinTop 我相信PutUint16 是 4 个字节而不是 2 个
  • uint16 是 16 位,2 个字节。

标签: python go encoding binary base64


【解决方案1】:

这是与您在 Go 中请求的 python 代码相同的代码:

    buf := []byte{128}
    encoded := base64.URLEncoding.EncodeToString(buf)

这段 Go 代码发生了什么?

buf := make([]byte, 4)
binary.LittleEndian.PutUint16(buf, uint16(128))                                                                                                                                                                
encoded := base64.URLEncoding.EncodeToString(buf)

如果您在此处输出buf 变量,您将看到它包含一些额外的0 字节:[128 0 0 0]。初始化长度为4的字节片时,会填充0s:[0 0 0 0]。然后将 128 添加到第一个位置。

当将字节切片编码为 base64 时,零字节也会被编码,从而产生不同的输出。


对于大于单个字节可以容纳的数字,如果不需要快速,您可以使用此代码:

buf := []byte(string(rune(1052)))

您也可以使用您采用的方法并忽略尾随零:

func encodeInt(val int) string {
    if val == 0 {
        return ""
    }
    buf := make([]byte, 8)
    binary.LittleEndian.PutUint64(buf, uint64(val))
    i := len(buf)
    for buf[i-1] == 0 {
        i--
    }
    return base64.URLEncoding.EncodeToString(buf[:i])
}

编辑:更正循环以占其间的 0 个字节。

【讨论】:

  • 您的for 循环错误。您需要从头开始检查(即从 i = 8 开始并检查 buf[i - 1] != 0 但如果 i == 1 停止,因为您不想在最后使用 i = 0 - 您可以使用 256 或 65536 进行测试以查看什么我的意思是)。
猜你喜欢
  • 2018-10-07
  • 1970-01-01
  • 2016-03-04
  • 2016-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多