天天看點

java:RSA加解密字元串與byte[]數組轉換 不用String方法的原因

RSA加密參考https://blog.csdn.net/qq_18870023/article/details/52596808

byte負數轉換參考https://bbs.csdn.net/topics/257493

  下圖是一個使用new String(); String.getBytes();方法進行轉換時變量的值。

java:RSA加解密字元串與byte[]數組轉換 不用String方法的原因

  在java中的byte[] 與 String 轉換,是周遊byte[] 把每個byte元素數值轉化為char 在放到String的char數組裡,例如byte[0] = 115 對應的char字元為 ‘s’ 。

  如果都是這樣的話,看起來直接用String方法進行轉換就行。

  但是, 觀察上圖 tempArr1,加密傳回的byte[]中存在負值,例如-116 。衆所周知,負數在Ascii碼中是沒有對應的值。

  在下圖中,由于new String(),采用檔案預設字元集UTF-8,處理時遇到解析不了的值,會用 ‘\uFFFD’代替,顯示為 ‘�’

  是以,再把byte[]進行轉換到String時,有負數就會出現錯誤,在上圖中就會展示為�。 此時,如果再把char � 轉換回byte的話 ,由于找不到對應的Ascii值,是以也就無法還原回以前的值。造成資料錯誤。

如圖所示

java:RSA加解密字元串與byte[]數組轉換 不用String方法的原因

  在上圖中,(byte)140顯示-116 是int 強轉隻保留後八位。byte數組 b 中有-116,55,其中-166被轉換成 �, 55被轉換成 7。再擷取 s.getBytes(); 可以發現 � 被轉換成了-17,-65,-67。

  此時的數組b1.length > b .length。 在使用Cipher解密時就會抛出異常。字元串長度超出。

  附上轉換工具類。

public class HexUtils {

    private static final char[] DIGITS = {
            '0', '1', '2', '3', '4', '5', '6', '7'
            , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    public static String bytesToHexString(byte[] data) {
        String string = "";
        try {
            char[] chars = new char[data.length << 1];
            //十六進制數一個四位,byte一個八位
            for (int i = 0, j = 0; i < data.length; i++) {
                chars[j++] = DIGITS[(data[i] >> 4) & 0x0F];
                chars[j++] = DIGITS[data[i] & 0x0F];
            }
            string = new String(chars);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return string;
    }

    public static byte[] hexStringToBytes(String data) {
        //兩個四位十六進制字元合成一個八位byte
        byte[] bytes = new byte[data.length() / 2];
        char[] chars = data.toCharArray();
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) ((hexCharToByte(chars[i * 2]) << 4) | hexCharToByte(chars[i * 2 + 1]));
        }
        return bytes;
    }

    private static byte hexCharToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}
           

  附上運作輸出圖

java:RSA加解密字元串與byte[]數組轉換 不用String方法的原因