如果我有一个32个字符的字符串(一个MD5哈希)并且我使用Base64对其进行编码,那么编码字符串的最大长度是多少?
答案 0 :(得分:39)
在Base64表示法中,MD5值始终为22(有用)字符长。在编码MD5哈希时,许多Base64算法还会附加2个填充字符,使总数达到24个字符。填充不会添加任何有用的信息,可以丢弃。只有前22个字符很重要。
原因如下:
MD5哈希值是128位值。 Base64字符串中的每个字符都包含6位信息,因为该字符有64个可能值,并且需要6个2的幂才能达到64.每个字符中有6位信息,21个字符有126位信息, 22个字符包含132位信息。由于128位不能容纳在21个字符内,但确实适合22个字符(有一点空间),128位值在Base64中始终表示为22个字符。
关于填充的说明:
我在上面提到过,许多Base64编码算法在编码MD5值时会添加几个填充字符。这是因为Base64将3个字节的信息表示为4个字符。由于MD5具有16个字节的信息,因此许多Base64编码算法附加“==”以指定16字节的输入比3的下一个倍数短2个字节,这将是18个字节。这两个等号不会对字符串添加任何信息,并且可以在存储时丢弃。
答案 1 :(得分:8)
根据http://en.wikipedia.org/wiki/Base64
“注意,给定n个字节的输入,输出将为(n + 2 - ((n + 2)%3))/ 3 * 4字节长,其收敛为n * 4/3或1.33333n对于大n。“
所以,它将是((32 + 2 - (32 + 2)%3))/ 3 * 4 = 34 - (34%3)/ 3 * 4 =(34 - 1)/ 3 * 4 = 33/3 * 4 = 44个字符。
你总是可以以原始二进制形式(128位)提取它并将其直接编码到base 64中,这意味着转换16个字节而不是32个字节,当base 64编码时它变为24个字节。
答案 2 :(得分:1)
MD5 128 位在 Base64 中表示为 22 个字符。在这种情况下也有 2 个填充字符 '='。
怎么样?
$ md5sum ./README.md
c6b5f48774aa0a87a82a276ff86be507 ./README.md
$ md5sum ./README.md | base64
YzZiNWY0ODc3NGFhMGE4N2E4MmEyNzZmZjg2YmU1MDcgIC4vUkVBRE1FLm1kCg==
在这种情况下 Base64 编码的字符串不短于 MD5 哈希长度
因为编码的是MD5 hash的存储形式。不是 MD5 哈希值本身。
需要注意用多少位来存储一位 MD5 哈希值。
正确的方法:
转换哈希值 1 十六进制转二进制
2 将二进制转换为 base64 编码的字符串
$ cat ./README.md | openssl dgst -md5
c6b5f48774aa0a87a82a276ff86be507
$ cat ./README.md | openssl dgst -md5 -binary | openssl enc -base64
xrX0h3SqCoeoKidv+GvlBw==
或
$ md5sum ./LICENSE
e3fc50a88d0a364313df4b21ef20c29e ./LICENSE
$ cat ./LICENSE | openssl dgst -md5 -binary | openssl enc -base64
4/xQqI0KNkMT30sh7yDCng==
$ (echo 0:; echo e3fc50a88d0a364313df4b21ef20c29e) | xxd -rp -l 16|base64
4/xQqI0KNkMT30sh7yDCng==