Golang十六进制编码

huangapple go评论83阅读模式
英文:

Golang hex encoding

问题

我正在尝试重新创建一个我在Python中找到的PKCS #5填充算法。

我遇到困难的主要部分是这一行:

return data + (chr(pad_count) * pad_count).encode('utf-8')

它实际上是将pad_count(一个介于1和16之间的整数)重复作为一个字符,重复1到16次。我在Go语言中很难得到类似的结果。

例如,pad_count为11将返回字符串:

\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b

我目前得到的最接近的结果是:

b := make([]byte, 2)
binary.LittleEndian.PutUint16(b, uint16(padCount))
fmt.Println("Pad: ", padCount, "Hex: ", hex.EncodeToString(b))

它将返回:

Pad: 11 Hex: 0b00

这已经非常接近了,显然我可以截取子字符串,并自己添加\x,但是否有更好的方法来解决这个问题呢?另外,如果我截取子字符串,我觉得不能保证适用于所有的组合情况。

英文:

I'm attempting to recreate a PKCS #5 Padding algorithm I've found written in python.

The main line I'm struggling to recreate is this

return data + (chr(pad_count) * pad_count).encode('utf-8')

which essentially repeats pad_count (an integer, between 1 and 16), as a char, between 1 and 16 times. I'm having trouble getting a similar result in Go.

For example, pad_count of 11 will return the string

\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b

The closeset I've come is this:

b := make([]byte, 2)
binary.LittleEndian.PutUint16(b, uint16(padCount))
fmt.Println("Pad: ", padCount, "Hex: ", hex.EncodeToString(b))

which will return:

Pad: 11 Hex: 0b00

This is pretty close, and obviously I could take a substring, and add the \x myself, but is there a better way to go about this? Also if I substring, I feel there is no guarantee that would work for all the combinations.

答案1

得分: 7

正如James Henstridge已经提到的,你想要的格式(\x0b...)并不是必需的,而是Python对不可打印字符的表示方式。你可以自己验证一下:

>>> chr(3)
'\x03'

你需要做的是在RFC2898中定义的:

[...] 其中填充字符串PS8-(||M|| mod 8)个八位字节组成,每个字节的值为8-(||M|| mod 8)。填充字符串PS将满足以下条件之一:

    如果 ||M|| mod 8 = 7,则 PS = 01;
    如果 ||M|| mod 8 = 6,则 PS = 02 02;
    ...
    如果 ||M|| mod 8 = 0,则 PS = 08 08 08 08 08 08 08 08。

这意味着你不需要使用uint16,而是使用uint8(因为一个八位字节只有8个位),也不需要按照Python的方式格式化字节。所以你需要做的只是使用bytes.Repeat

bytes.Repeat(paddingChar, paddingCount)
英文:

As James Henstridge already mentioned the formatting you want (\x0b...) is not something that's required but rather python's representation of non-printable characters. See for yourself:

>>> chr(3)
'\x03'

What you have to do is defined in RFC2898:

> [...] where the padding string PS consists of 8-(||M|| mod 8) octets
> each with value 8-(||M|| mod 8). The padding string PS will
> satisfy one of the following statements:
>
> PS = 01, if ||M|| mod 8 = 7 ;
> PS = 02 02, if ||M|| mod 8 = 6 ;
> ...
> PS = 08 08 08 08 08 08 08 08, if ||M|| mod 8 = 0.

This means that you do not need uint16 but uint8 (since an octet has only 8 bits) and you also do not need to format your bytes the way python does. So the only thing you have to do is to use bytes.Repeat:

bytes.Repeat(paddingChar, paddingCount)

答案2

得分: 0

func pad(input []byte, pad_count int) []byte {
out := make([]byte, len(input) + int(pad_count))
copy(out, input)
for i := 0; i < pad_count; i++ {
out[len(input) + i] = byte(pad_count)
}
return out
}

英文:
func pad(input []byte, pad_count int) []byte {
	out := make([]byte, len(input) + int(pad_count))
	copy(out, input)
	for i := 0; i &lt; pad_count; i++ {
		out[len(input) + i] = byte(pad_count)
	}
	return out
}

huangapple
  • 本文由 发表于 2014年5月27日 22:39:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/23892355.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定