如果我有一个 32 个字符的字符串(一个 MD5 哈希)并且我使用 Base64 对其进行编码,那么编码字符串的最大长度是多少?
3 回答
在 Base64 表示法中,MD5 值始终是 22 个(有用的)字符长。许多 Base64 算法在编码 MD5 散列时还会附加 2 个填充字符,使总数达到 24 个字符。填充没有添加有用的信息,可以丢弃。只有前 22 个字符很重要。
原因如下:
MD5 哈希是一个 128 位的值。Base64 字符串中的每个字符包含 6 位信息,因为该字符有 64 个可能的值,需要 2 的 6 次方才能达到 64。每个字符包含 6 位信息,21 个字符有 126 位信息, 22 个字符包含 132 位信息。由于 128 位不能容纳在 21 个字符内,但可以容纳在 22 个字符内(留出一点空间),因此 128 位值在 Base64 中将始终表示为 22 个字符。
关于填充的注释:
我在上面提到,许多 Base64 编码算法在编码 MD5 值时会添加几个填充字符。这是因为 Base64 将 3 个字节的信息表示为 4 个字符。由于 MD5 有 16 个字节的信息,许多 Base64 编码算法会附加“==”来指定 16 个字节的输入比下一个 3 的倍数少 2 个字节,即 18 个字节。这两个等号不向字符串添加任何信息,并且可以在存储时丢弃。
根据http://en.wikipedia.org/wiki/Base64
“请注意,给定 n 字节的输入,输出将是 (n + 2 - ((n + 2) % 3)) / 3 * 4 字节长,对于大 n 收敛到 n * 4 / 3 或 1.33333n 。”
因此,它将是 ((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 个字节。
MD5 128 位在 Base64 中表示为 22 个字符。在这种情况下也有 2 个填充字符“=”。
如何?
$ md5sum ./README.md
c6b5f48774aa0a87a82a276ff86be507 ./README.md
$ md5sum ./README.md | base64
YzZiNWY0ODc3NGFhMGE4N2E4MmEyNzZmZjg2YmU1MDcgIC4vUkVBRE1FLm1kCg==
在这种情况下,Base64 编码的字符串不短于 MD5 哈希长度
因为编码的是MD5哈希的存储形式。不是 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==