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

Java 字符串中的前两个字节:转换行为?,java,arrays,string,data-conversion,Java,Arrays,String,Data Conversion,我有一个字节数组,它是一个文件的散列。这是用messageDigest生成的,因此有一个填充。然后我做一个shorthash,它只是hash的前两个字节,如下所示: byte[] shorthash = new byte[2]; System.arraycopy(hash, 0, shortHash, 0, 2); 为了让用户可读并将其保存在数据库中,我使用Base64编码器将其转换为字符串: Base64.getUrlEncoder().encodeToString(hash); //S

我有一个字节数组,它是一个文件的散列。这是用
messageDigest
生成的,因此有一个填充。然后我做一个shorthash,它只是hash的前两个字节,如下所示:

 byte[] shorthash = new byte[2];
 System.arraycopy(hash, 0, shortHash, 0, 2);
为了让用户可读并将其保存在数据库中,我使用
Base64编码器将其转换为字符串:

Base64.getUrlEncoder().encodeToString(hash); //Same for shorthash
我不明白的是:

  • 为什么表示我的shorthash的字符串有四个字符长?我认为一个字符是一个或两个字节,所以因为我只复制了两个字节,所以我不应该有两个以上的字符,对吗

  • 为什么我的shorthash字符串与hash字符串的开头不一样

  • 例如,我将有:

    Hash: LE5D8vCsMp3Lcf-RBwBRbO1v4soGq7BBZ9kB_2SJnGY=
    Shorthash: Rak=
    
    您可以在每个页面的末尾看到
    =
    ;它当然来自于
    MessageDigest
    padding,所以散列是正常的,但是为什么是shorthash呢?它应该是前两个字节,
    =
    在末尾

    此外:由于我想去掉这种填充物,我决定这样做:

    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);
    
    我不想直接复制字符串,因为我不确定字符串中的两个字节是什么

    然后,
    =
    将用于我的hash,但不用于我的shorthash。我想我需要将“withoutPadding”选项添加到我的shorthash中,但我不明白为什么,因为它是我的hash的一个副本,不应该再添加填充。除非填充仅在字符串表示上,而不在其后面的字节中

    有人能解释这种行为吗?它是否来自字节[]和字符串之间的转换

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

    因为你对它进行了base64编码。每个base64数字正好代表6位数据。你有16位。2位是不够的(只有12位),所以需要3位来表示这些位。第四位是填充,因为base64通常被规范化为4位的倍数。

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


    因为你对它进行了base64编码。每个base64数字正好代表6位数据。你有16位。2位是不够的(只有12位),所以需要3位来表示这些位。第四位是填充,因为base64通常被规范化为4位的倍数。

    base64需要一个字节来编码6位,因此base64编码的字符串应该比初始字节序列长。您能将两个字节的数组转换为十六进制字符串吗?因此,在审查中,它将比基本的64 stringThx更具可读性。是的,我想我可以用十六进制,Base64只是我找到的第一个解决方案。我能做到,但我还是想了解斯特拉涅在这里的行为@tkausl给出了第一个问题的答案,谢谢!Base64最多可填充四的倍数(尽管在某些Base64方案中,填充是可选的)。此填充与哈希方案中的任何填充无关。Base64需要一个字节来编码6位,因此Base64编码的字符串应该比初始字节序列长。能否将两个字节的数组转换为十六进制字符串?因此,在审查中,它将比基本的64 stringThx更具可读性。是的,我想我可以用十六进制,Base64只是我找到的第一个解决方案。我能做到,但我还是想了解斯特拉涅在这里的行为@tkausl给出了第一个问题的答案,谢谢!Base64最多可填充四的倍数(尽管在某些Base64方案中,填充是可选的)。此填充与哈希方案中的任何填充无关。类似地,32字节哈希(可能是SHA-256或SHA3-256?)为256位,256/6>42,因此在base64中需要43位加1个pad char,类似地,32字节哈希(可能是SHA-256或SHA3-256?)为256位,256/6>42,因此在base64中需要43位加1个pad char