Java十六進制字符串與二進制數組互轉、&0xff的作用


十六進制字符串轉字節數組

/**
     * 功能: 十六進制字符串轉字節數組
     * @param hexString 十六進制字符串
     * @return 字節數組
     */
    public static byte[] convertHexStringToBytes(String hexString){
        //判空
        if(hexString == null || hexString.length() == 0) {
            return null;
        }

        //合法性校驗
        if(!hexString.matches("[a-fA-F0-9]*") || hexString.length() % 2 != 0) {
            return null;
        }

        //計算
        int mid = hexString.length() / 2;
        byte[]bytes = new byte[mid];
        for (int i = 0; i < mid; i++) {
            bytes[i] = Integer.valueOf(hexString.substring(i * 2, i * 2 + 2), 16).byteValue();
        }

        return bytes;
    }

字節數組轉十六進制字符串

    /**
     * 字節數組轉16進制數
     * @param bytes 字節數組
     * @return 返回值
     */
    public static String convertBytesToHexString(byte[]bytes) {
        StringBuilder res = new StringBuilder("");
        for (byte aByte : bytes) {
            String temp = Integer.toHexString(aByte & 0xff);
            if (temp.length() == 1) {
                temp = '0' + temp;
            }
            res.append(temp);
        }
        return res.toString().toUpperCase();
    }

 

整數轉化為十六進制字符串

 /**
     * 功能:將整數轉化為合法的十六進制字符串
     * @param source 整數
     * @param len 至少占多少個字節
     * @return 十六進制數
     *
     * 說明:為什么要有len?
     * 某些場景需要指定大小的二進制字符串(這里的大小指的是轉化為字節數組后所占大小)
     * 例如,現在需要把1這個整數轉化為十六進制數,
     * 如果len為1,結果為 01
     * 如果len為2,結果為 0001
     *
     * 但是len不限制大小,比如len設置為1,source為125120,那么結果仍然為1e8c0,
     * 不會截斷結果
     */
    public static String convertIntToHexString(int source, int len) {
        //一個字節占兩位,所以要乘以2
        len <<= 1;
        StringBuilder res = new StringBuilder(Integer.toHexString(source));
        int comp = len - res.length();

        //位數不足,需要補0
        if(comp > 0) {
            for (int i = 0; i < comp; i++) {
                res.insert(0, "0");
            }
        }

        return res.toString();
    }

個人理解

上文提及的“合法十六進制字符串”指的是什么?

需要滿足如下條件:

1、只能包含數字以及字母ABCDEF(包含大小寫)

2、字符的個數必須是雙數,比如“1”只能寫成“01”

&0xff 到底有什么含義?

首先我們先了解一下基本作用

1 & 0 = 0

1 & 1 = 1

0 & 0 = 0

計算機中二進制數都是以補碼的形式存在

a & 0xff 表示取 a 補碼的后八位。

 

16進制字符串的范圍是 0x00 到 0xff,0到255

java中的byte是有符號的,一個byte表示的范圍是  -128到127。

而在這里,我們不需要byte的符號屬性,只需要它老老實實的表示0到255即可,所以不得不將128到255之間的數據做一個映射。

換句話說,11111111(補碼), 如果最高位作為符號位, 它是-1,如果不作為符號位,那就能表示255.

    public static void main(String[] args) {
          byte a = -1;
          int b = a & 0xff;
          System.out.println(a);
          System.out.println(b);
    }

結果是:

-1
255

a & 0xff的返回值是int,也就是說,將a這個字節的補碼原封不動的拿出來,放到int中。

因為int 是四個字節,我們現在只用了兩個字節,自然觸碰不到符號位,這么一操作,就可以將 -1 映射成 255。

這樣就可以理解字節轉字符串中的這個轉換了:

Integer.toHexString(aByte & 0xff);

 

簡而言之,我們確實需要存256個數,但是范圍是0-255,而不是 -128-127,因為java不支持unsigned byte這種數據類型,所以我們需要借助容量更大的int完成這一轉換。

換句話說,如果java支持無符號byte,就不需要做這種轉換了。(C#中的byte就是沒有符號的,sbyte才是有符號的)

關於原碼、補碼、反碼的相關概念,推薦文章:  https://zhuanlan.zhihu.com/p/91967268

 

如有錯誤,懇請批評指正!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM