对于字节,16进制,2进制,& 0xFF,位移的一些杂记

文章详细阐述了如何在Java中将普通字符串转换为16进制字符串,以及16进制字符串与字节、二进制之间的相互转换。同时,讨论了位操作如&0xFF在处理二进制数据时的作用,包括取得低八位、五位和四位的技巧。此外,还介绍了位移运算符(<<,>>,>>>)的功能和应用实例。
摘要由CSDN通过智能技术生成

1.普通字符串95 对应的16进制的展示,使用工具查看如下图

下图为普通字符串

下图为95对应的16进制

 

 95对应的16进制字符串为39 35=》39代表一个字节  35代表另一个字节  (一个字节是由两位16进制字符串组成,比如39或35)

1个字节对应8个二进制数位

39 拆分为 3跟9  3对应的二进制0011  9对应的二进制1001 (共8位二进制)

35 拆分为 3跟5  3对应的二进制0011  5对应的二进制0101 (共8位二进制)

使用JAVA类进行测试

//95为普通字符串
String s12 = ConverterUtil.stringToHexString("95");//字符串转换为十六进制字符串
System.out.println("s12:"+s12);//打印结果为 3935
//95对应的16进制字符串为 39 35
byte[] bytes = "95".getBytes("GBK");
System.out.println(bytes.length);
//bytes[0] bytes[1]需要 ConverterUtil.byteToHex转成16进制字符串
System.out.println(bytes[0]);//值为57 57可能是ASCII,要通过 ConverterUtil.byteToHex来转化才是39  
System.out.println(bytes[1]);//值为53 53可能是ASCII,要通过 ConverterUtil.byteToHex来转化才是35  

//字节转为16进制字符串
byte num = bytes[0] ;
String s2 = ConverterUtil.byteToHex(num);
System.out.println("s2:" + s2);//39

num = bytes[1] ;
String s21 = ConverterUtil.byteToHex(num);
System.out.println("s21:" + s21);//35

//字节数组转为16进制字符串
String s7 = ConverterUtil.encodeHexString(bytes);
System.out.println("s7:"+s7);//相当于每个字节转16进制字符串 3935
//十六进制字符串转二进制转字符串
String s9 = ConverterUtil.hex2bin(s7);
System.out.println("s9:"+s9);//0011100100110101=>0011|1001|0011|0101=> 3 9 3 5

& 0xFF的意义及作用
&表示按位与,只有两个位同时为1,才能得到1
0x代表16进制数
0xFF表示的数二进制1111 1111
& 0xFF作用是为了取得低八位
例子 :0x1234
0x1234 表示为二进制 0001001000110100
0xFF表示为二进制 11111111
两个数做与操作 将0xFF补充到16位,就是高位补0 ,此时0xFF为 0000000011111111
与操作 1&0 =0,1&1 =1 这样 0x1234只能保留低八位的数 0000000000110100 也就是 0x34

& 0x1F作用是为了取得低五位
0x1F表示的数二进制0001 1111

&0x0F呢 作用是为了取得低四位
0x0F表示的数二进制0000 1111

位移用法

<< 左移运算符,右边空出的位用0填补,高位左移溢出则舍弃该高位:num << 1,相当于num乘以2
>> 右移运算符,左边空出的位用0或者1填,正数用0负数用1填,低位右移溢出则舍弃该位。num >> 1,即num除以2
>>>无符号右移,忽略符号位,空位都以0补齐

例子

((3 >>> 8) & 0xFF)  无符号右移8位,后再取低8位
((3 >>> 0) & 0xFF)  无符号右移0位,后再取低8位
0000,0000,0000,0011     3的二进制原码,
0000,0000,0000,0000     这是">>>8"的结果           
                  1111,1111       然后再 &0XFF     
                 0000,0000       最终结果   
这就得到了 3的原码0000,0000,0000,0011 的高8位(0000,0000)


0000,0000,0000,0011     3的二进制原码,
0000,0000,0000,0011     这是">>>0"的结果(还是源码本身不变)
                   1111,1111       然后再 &0XFF     
                  0000,0011       最终结果  
这就得到了 3的原码0000,0000,0000,0011 的低8位(0000,0011)

常见转化工具类

/**
 * 转换工具类
 */
public class ConverterUtil {

    /**
     * 字节转16进制字符串
     * @param num
     * @return
     */
    public static String byteToHex(byte num) {
        char[] hexDigits = new char[2];
        hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
        hexDigits[1] = Character.forDigit((num & 0xF), 16);
        String hexDigitsStr = new String(hexDigits) ;
        return hexDigitsStr;
    }

    /**
     * 16进制字符串转字节
     * @param hexString
     * @return
     */
    public static byte hexToByte(String hexString) {
        int firstDigit = toDigit(hexString.charAt(0));
        int secondDigit = toDigit(hexString.charAt(1));
        return (byte) ((firstDigit << 4) + secondDigit);
    }

    /**
     * 16进制字符串转10进制
     * @param hexChar
     * @return
     */
    private static  int toDigit(char hexChar) {
        int digit = Character.digit(hexChar, 16);
        if(digit == -1) {
            throw new IllegalArgumentException(
                    "Invalid Hexadecimal Character: "+ hexChar);
        }
        return digit;
    }

    /**
     * 字节数组转十六进制字符串
     * @param byteArray
     * @return
     */
    public static String encodeHexString(byte[] byteArray) {
        StringBuffer hexStringBuffer = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            hexStringBuffer.append(byteToHex(byteArray[i]));
        }
        return hexStringBuffer.toString();
    }

    /**
     * 十六进制字符串转字节数组
     * bcd2hex跟decodeHexString结果一样
     * @param hexString  16进制字符串  如 9F33
     * @return
     */
    public static byte[] decodeHexString(String hexString) {
        if (hexString.length() % 2 == 1) {
            throw new IllegalArgumentException(
                    "Invalid hexadecimal String supplied.");
        }
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            bytes[i / 2] = hexToByte(hexString.substring(i, i + 2));
        }
        return bytes;
    }


    /**
     * 字符串转换为十六进制字符串
     * @param s
     * @return
     */
    public static String stringToHexString(String s) {
        String str = "";
        for (int i = 0; i < s.length(); i++) {
            int ch = s.charAt(i);
            String s4 = Integer.toHexString(ch);
            str = str + s4;
        }
        return str;
    }

    /**
     * 十六进制字符串转换为字符串
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(
                        s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "gbk");
//            new String();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    /**
     * 字符串转换为E码字符串
     * @param s
     * @return
     */
    public static String stringToEbcdicString(String s) throws Exception{
        byte[] bytes = s.getBytes("Cp1047");
        StringBuilder result = new StringBuilder();
        for (byte aByte : bytes) {
            int decimal = (int) aByte & 0xff;               // bytes widen to int, need mask, prevent sign extension
            // get last 8 bits
            String hex = Integer.toHexString(decimal);
            if (hex.length() % 2 == 1) {                    // if half hex, pad with zero, e.g \t
                hex = "0" + hex;
            }
            result.append(hex);
        }
        return result.toString().toUpperCase();

    }

    /**
     * E码字符串转换为字符串
     * @param s
     * @return
     */
    public static String ebcdicStringToString(String s) {
        if (s == null || s.equals("")) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(
                        s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "Cp1047");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    /**
     * 二进制转字符串转十六进制字符串
     * @param input
     * @return
     */
    public static String bin2hex(String input) {
        StringBuilder sb = new StringBuilder();
        int len = input.length();
        System.out.println("原数据长度:" + (len / 8) + "字节");

        for (int i = 0; i < len / 4; i++){
            //每4个二进制位转换为1个十六进制位
            String temp = input.substring(i * 4, (i + 1) * 4);
            int tempInt = Integer.parseInt(temp, 2);
            String tempHex = Integer.toHexString(tempInt).toUpperCase();
            sb.append(tempHex);
        }

        return sb.toString();
    }

    /**
     * 十六进制字符串转二进制转字符串
     * @param input
     * @return
     */
    public static String hex2bin(String input) {
        StringBuilder sb = new StringBuilder();
        int len = input.length();
//        System.out.println("原数据长度:" + (len / 2) + "字节");

        for (int i = 0; i < len; i++){
            //每1个十六进制位转换为4个二进制位
            String temp = input.substring(i, i + 1);
            int tempInt = Integer.parseInt(temp, 16);
            String tempBin = Integer.toBinaryString(tempInt);
            //如果二进制数不足4位,补0
            if (tempBin.length() < 4){
                int num = 4 - tempBin.length();
                for (int j = 0; j < num; j++){
                    sb.append("0");
                }
            }
            sb.append(tempBin);
        }

        return sb.toString();
    }

    /**
     * bcd字符串(双数)转成字节码
     * bcd2hex跟decodeHexString结果一样
     * @param input 16进制字符串  如 9F33
     * @return
     */
    public static byte[] bcd2hex(String input){
        if(input==null || input.length()==0){
            return new byte[]{};
        }
        byte[] bs = new byte[input.length()/2];
        for(int i=0 ;i<input.length();i++){
            int x = Integer.parseInt(input.substring(i,i+2),16);
            bs[i/2] = (byte)x;
            i++ ;
        }
        return bs ;
    }

    /**
     * 字节码转成bcd字符串
     * @param input
     * @return
     */
    public static String hex2bcd(byte[] input){
        StringBuilder builder = new StringBuilder();
        if(input!=null && input.length!=0){
            for(int i=0 ;i<input.length;i++){
                int v = input[i] & 0xFF ;
                String hv = Integer.toHexString(v);
                if(hv.length()<2){
                    builder.append(0);
                }
                builder.append(hv.toUpperCase());
            }
        }
        return builder.toString();
    }

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值