我有一个字节数组,它是文件的哈希值。这是使用messageDigest
进行的,因此存在填充。然后,我创建一个shorthash,它只是哈希的前两个字节,如下所示:
byte[] shorthash = new byte[2];
System.arraycopy(hash, 0, shortHash, 0, 2);
为了使用户可读并将其保存在数据库中,我正在使用Base64 Encoder
将其转换为String:
Base64.getUrlEncoder().encodeToString(hash); //Same for shorthash
我不明白的是:
为什么代表我的shorthash的字符串长四个字符?我以为一个字符是一个或两个字节,所以既然我只复制两个字节,那么我不应该有两个以上的字符,对吗?
为什么我的shorthash字符串与哈希字符串的开头不同?
例如,我要:
Hash: LE5D8vCsMp3Lcf-RBwBRbO1v4soGq7BBZ9kB_2SJnGY=
Shorthash: Rak=
您可以在每个结尾处看到=
;它肯定来自MessageDigest
填充,因此散列是正常的,但是为什么要使用shorthash?它应该是两个FIRST字节,=
在结尾!
此外:由于我想摆脱这种填充,所以我决定这样做:
String finalHash = Base64.getUrlEncoder().withoutPadding().encodeToString(hash);
byte[] shorthash = new byte[2];
System.arraycopy(hash.getBytes(), 0, shortHash, 0, 2);
String finalShorthash = Base64.getUrlEncoder().encodeToString(shorthash);
我不想直接复制String,因为我不确定字符串中的两个字节。
然后,=
用于我的哈希,但不用于我的shorthash。我想我需要在我的shorthash中添加“ withoutPadding”选项,但是我不明白为什么,因为这是我的哈希的副本,不再需要填充。除非填充仅在字符串表示形式上而不在其后面的字节上消失了?
有人可以解释这种行为吗?它是否来自byte []与String之间的转换?
答案 0 :(得分:2)
“为什么代表我的shorthash的字符串长四个字符?”
因为您对base64进行了编码。每个base64位代表6位数据。您有16位。 2位数字是不够的(仅12位),因此您需要3位数字来表示这些位。第4位是填充字符,因为base64通常会标准化为4位的倍数。