zoukankan      html  css  js  c++  java
  • 字节数组与16进制字符串的相互转换

    众所周知,二进制数据(包括内存地址)在计算机中一般以16进制的方式表示,大家也习惯使用16进制来查看、记录二进制数据,所以看了一下Java中字节与16进制的相互转换。因为大多数情况下我们遇到的都是字节数组,所以本文是以字节数据与16进制字符串的相互转换为例。

    先说一下看字节与16进制转换问题的缘由。在项目中,我准备写一个MD5的工具方法,使用的是JDK自带的 MessageDigest 信息摘要类,代码如下:

    MessageDigest md5Digest = MessageDigest.getInstance("MD5");
    byte[] btArr = md5Digest.digest(str.getBytes());

    很明显,我在调用了信息摘要方法之后,得到的是一个字节数组 byte[] ,而我想要的 MD5 方法应该是像大多数md5工具一样,返回一个 32 位的字符串。

    简单查了一下,才知道原来 MD5 信息摘要算法返回的结果是一个 128 bit 的二进制数据,128 bit 正好是 16个 byte,而1个byte转成16进制正好是2位(16进制使用4个bit,一个byte有8个bit),所以MD5算法返回的128bit 转成 16进制就正好是 32位。

    听着可能有点绕,简单的说,上述代码中md5信息摘要之后,返回了一个有 16个字节的字节数组,而现在需要做的就是把这个字节数组转成16进制格式的数据。

    回到正题,字节与16进制相互转换的代码如下:

    public class HexTest {
    
        private static final char HexCharArr[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
    
        private static final String HexStr = "0123456789abcdef";
    
        public static String byteArrToHex(byte[] btArr) {
            char strArr[] = new char[btArr.length * 2];
            int i = 0;
            for (byte bt : btArr) {
                strArr[i++] = HexCharArr[bt>>>4 & 0xf];
                strArr[i++] = HexCharArr[bt & 0xf];
            }
            return new String(strArr);
        }
    
        public static byte[] hexToByteArr(String hexStr) {
            char[] charArr = hexStr.toCharArray();
            byte btArr[] = new byte[charArr.length / 2];
            int index = 0;
            for (int i = 0; i < charArr.length; i++) {
                int highBit = HexStr.indexOf(charArr[i]);
                int lowBit = HexStr.indexOf(charArr[++i]);
                btArr[index] = (byte) (highBit << 4 | lowBit);
                index++;
            }
            return btArr;
        }
    }
    byteArrToHex 字节数组转成16进制字符串
    基本的算法是:把一个字节分成高4位的bit和低4位的bit,先取高4位的bit,得到这4位bit对应的数字(范围在0~15),就可以知道对应的16进制数是多少了;按同样的方式取到低4位bit对应的16进制数,把这些16进制数放到一个数组里,最后串成一个字符串,就得到了我们需要的16进制字符串。

    hexToByteArr 16进制字符串转成字节数组
    基本的算法是:把16进制字符串分成一个的char数组,循环取其中的两个char,这两个char的值一定都是在[0123456789abcdef]之间;先找到第一个char对应的下标位置,比如说char的值为 a,那么下标位置就是 10,把数字10转
    成byte类型,取低4位bit,然后用同样的方式找到第二个char对应的下标数字,取到该数字的低4位bit;将刚才取到的两个低4位bit拼在一起,第一个char对应的4位bit为字节的高4位,第二个char对应的4位bit为字节的低4位,这样组成一个完整的8bit字节;循环完char数组,就得到了16进制字符串对应的字节数组。

    因16进制只需占用4个bit,而一个字节有8个bit,所以字节转16进制的时候需要拆开来转换,一个字节对应两个16进制字符;而16进制字符串转成字节的时候,需要用两个16进制数对应的bit拼接起来才能组成一个完整的字节,转换后得到的字节数组的长度是16进制字符串长度的一半。
    (完)
  • 相关阅读:
    Java基础课程---将一个字符串反转,将字符串中指定部分进行反转,比如,"abcdefg", 反转为"abfedcg"
    在Centon64位中卸载安装时系统自带的--openjdk,并且安装自己需要的jdk
    Java基础课程---sleep()方法 和 wait()方法的异同(面试题)
    Java基础课程---权限修饰符
    Java基础课程---
    MySQL 创建库
    brew
    android webview load 本地文件需要注意的地方
    android下隐藏标题栏
    android webview无法加载网页
  • 原文地址:https://www.cnblogs.com/zhaoyue1215/p/10449530.html
Copyright © 2011-2022 走看看