Hash 为什么base64编码的SHA-1哈希包含56个字符?

Hash 为什么base64编码的SHA-1哈希包含56个字符?,hash,base64,encode,sha1,Hash,Base64,Encode,Sha1,也许这是个很愚蠢的问题,但我就是想不出来 首先,我需要使用提交标记的一部分生成SHA-1哈希。哈希正确,输出正确 0623f7917a1e2e09e7bcc700482392fba620e6a2 接下来,我需要将这个散列编码为一个28个字符的序列号。这就是我正在努力的地方,因为当我运行代码(或使用在线生成器)时,我得到了一个56个字符的提示。我受到的刺痛是 mdyym2y3ote3ytflmmuwowu3ymnjawndgymzyzmjhnjiwztzhmg== 问题是1)是否可以从上面的散列中

也许这是个很愚蠢的问题,但我就是想不出来

首先,我需要使用提交标记的一部分生成SHA-1哈希。哈希正确,输出正确

0623f7917a1e2e09e7bcc700482392fba620e6a2

接下来,我需要将这个散列编码为一个28个字符的序列号。这就是我正在努力的地方,因为当我运行代码(或使用在线生成器)时,我得到了一个56个字符的提示。我受到的刺痛是

mdyym2y3ote3ytflmmuwowu3ymnjawndgymzyzmjhnjiwztzhmg==

问题是1)是否可以从上面的散列中获取28个字符的字符串?2)如何。。。我哪里会出错呢


感谢您提供的帮助。

SHA-1哈希值的长度为20字节,但这些字节不太可能都是可打印字符。 因此,如果我们想向人类显示这20个字节,我们必须用可打印字符对它们进行编码

一种方法是,我们将每个字节切成两半,并用
0123456789abcdef
范围内的字符表示每一半(一个4位值,数字为0-15)。 因此,每个字节被编码为2个十六进制值,因此我们的20字节哈希值被编码为40字节的可打印字符

十六进制很容易计算,人类很容易查看编码并计算出字节的实际外观,但它不是最有效的,因为我们只使用了95个ASCII可打印字符中的16个

将任意二进制数据编码为可打印字符的另一种方法是。这更有效,在4个base64值中编码(平均)3个字节,但对人类来说解析编码要困难得多

您看到的行为是将20字节的哈希值编码为40字节的十六进制,然后将40字节的十六进制编码为56字节(
40/3*4
,然后四舍五入到最接近的4字节)的base64数据


您需要从原始哈希字节(如果可用)直接编码到base64,或者在编码到base64之前将十六进制值解码为字节。

SHA-1哈希长度为20字节,但这些字节不可能都是可打印字符。 因此,如果我们想向人类显示这20个字节,我们必须用可打印字符对它们进行编码

一种方法是,我们将每个字节切成两半,并用
0123456789abcdef
范围内的字符表示每一半(一个4位值,数字为0-15)。 因此,每个字节被编码为2个十六进制值,因此我们的20字节哈希值被编码为40字节的可打印字符

十六进制很容易计算,人类很容易查看编码并计算出字节的实际外观,但它不是最有效的,因为我们只使用了95个ASCII可打印字符中的16个

将任意二进制数据编码为可打印字符的另一种方法是。这更有效,在4个base64值中编码(平均)3个字节,但对人类来说解析编码要困难得多

您看到的行为是将20字节的哈希值编码为40字节的十六进制,然后将40字节的十六进制编码为56字节(
40/3*4
,然后四舍五入到最接近的4字节)的base64数据


您需要从原始散列字节(如果可用)直接编码到base64,或者在编码到base64之前将十六进制值解码为字节。

您需要28个字符的字符串到底有什么用?如果您不介意将一些散列计算为相同的值,您可以只取一个子字符串。但是如果你需要一个完全唯一的散列,你必须找到另一种方法。你的目标是什么语言?2) 十六进制值被编码为文本(
“062…”
=
0x30、0x36、0x32,…
),而不是它所代表的大数字。@Jonathan-我被你的评论难住了。您能否详细说明一下,您是如何得出“MDY”是062的字符串表示形式的结论的?我完全忽略了它:/@SteveK
MDYy…
是字符串
“0623…”
–48、54、50、51等下面的代码点序列,用base-64表示。虽然
0623…
是十六进制的,但它存储为字符串(
“0”
“9”
“a”
“f”
)。要从base-16转换为base-64,必须首先将字符串解析为数字序列–0x6、0x23、0xf7等。您需要28个字符的字符串的确切用途是什么?如果您不介意将一些散列计算为相同的值,您可以只取一个子字符串。但是如果你需要一个完全唯一的散列,你必须找到另一种方法。你的目标是什么语言?2) 十六进制值被编码为文本(
“062…”
=
0x30、0x36、0x32,…
),而不是它所代表的大数字。@Jonathan-我被你的评论难住了。您能否详细说明一下,您是如何得出“MDY”是062的字符串表示形式的结论的?我完全忽略了它:/@SteveK
MDYy…
是字符串
“0623…”
–48、54、50、51等下面的代码点序列,用base-64表示。虽然
0623…
是十六进制的,但它存储为字符串(
“0”
“9”
“a”
“f”
)。要从base-16转换为base-64,必须首先将字符串解析为数字序列–0x6、0x23、0xf7等。