字符串中的前两个字节:转换行为?

时间:2018-09-01 09:58:42

标签: java arrays string data-conversion

我有一个字节数组,它是文件的哈希值。这是使用messageDigest进行的,因此存在填充。然后,我创建一个shorthash,它只是哈希的前两个字节,如下所示:

 byte[] shorthash = new byte[2];
 System.arraycopy(hash, 0, shortHash, 0, 2);

为了使用户可读并将其保存在数据库中,我正在使用Base64 Encoder将其转换为String:

Base64.getUrlEncoder().encodeToString(hash); //Same for shorthash

我不明白的是:

  1. 为什么代表我的shorthash的字符串长四个字符?我以为一个字符是一个或两个字节,所以既然我只复制两个字节,那么我不应该有两个以上的字符,对吗?

  2. 为什么我的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之间的转换?

1 个答案:

答案 0 :(得分:2)

“为什么代表我的shorthash的字符串长四个字符?”

因为您对base64进行了编码。每个base64位代表6位数据。您有16位。 2位数字是不够的(仅12位),因此您需要3位数字来表示这些位。第4位是填充字符,因为base64通常会标准化为4位的倍数。