Java处理16进制字符串方法记录



不得不说AI是最擅长处理类似的需求的,比方16进制字符串转换为byte数组,字符串中含有0xff的字符串。

原来写的代码始终转不了带ff的十六进制字符串,然后用文言一心一试,居然一次就过了。


下面是代码:

public static byte[] hexStringToByteArray(String hexString) {
    int len = hexString.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                + Character.digit(hexString.charAt(i+1), 16));
    }
    return data;
}


原来写的转换方法失效,原因是处理0xff失效了,代码如下:

/**
 * 十六进制转byte字节
 * @param hexString
 * @return
 */
public static byte hexToByte(String hexString) {
    int firstDigit = toDigit(hexString.charAt(0));
    int secondDigit = toDigit(hexString.charAt(1));
    if (firstDigit == 0 && secondDigit == 0){
        return 0x2E;//-
    }
    if(firstDigit > 7){
        return 0x2E;//.
    }
    return (byte) ((firstDigit << 4) + secondDigit);
}

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) {
    if(byteArray==null){
        return "";
    }
    StringBuffer hexStringBuffer = new StringBuffer();
    for (int i = 0; i < byteArray.length; i++) {
        hexStringBuffer.append(byteToHex(byteArray[i]));
    }
    return hexStringBuffer.toString().toUpperCase();
}

/**
 * 十六进制转字节数组
 * @param hexString
 * @return
 */
public static byte[] decodeHexString(String hexString) {
    if (hexString == null){
        return new byte[1];
    }
    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;
}


打印16进制;

public static void printHexString(String hint, byte[] b) {
    Log.i(TAG, hint);
    if (b == null){
        return;
    }
    for (int i = 0; i < b.length; i++) {
        String hex = Integer.toHexString(b[i] & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        Log.i(TAG, hex.toUpperCase() + " ");
    }
    System.out.println("");
}


java中的byte不是无符号整数,那么如何将byte变量判断0xff.

byte value = 0xff;
int header = (int)(value & 0xff);
if (header  != 0xFF){
    return data;
}



转义处理:

static int escapte_fun(byte []out_data, byte[] sb, int sb_len){
    int indx = 0;
    int pos_sb = 0;
    out_data[indx++] = (byte)sb[pos_sb++];  //head
    int tmp_dlen =sb_len - 1;
    /*消息转义,从包类型到消息体内容*/
    for (int i=1; i<tmp_dlen; i++)
    {
        int value = (byte)sb[i] & 0xff;
        if (0xFF == value)
        {
            out_data[indx++] = (byte)0xFD;
            out_data[indx++] = (byte)0x02;
        }
        else if (0xFE == value)
        {
            out_data[indx++] = (byte)0xFD;
            out_data[indx++] = (byte)0x01;
        }
        else if (0xFD == value)
        {
            out_data[indx++] = (byte)0xFD;
            out_data[indx++] = (byte)0x00;
        }
        else
        {
            out_data[indx++] = (byte)sb[i];
        }
    }

    out_data[indx++] = (byte)0xFE;
    return indx;
}
static void de_escabe_data(byte[] input, byte[] output){
    int j= 0;
    int i=0;
    for (; i<input.length-2; i++){
        int value = (byte)input[i] & 0xff;
        int value_2 = (byte)input[i+1] & 0xff;
        if (0xFD == value && value_2 == 0x02 )
        {
            output[j++] = (byte)0xFF;
            i++;
        }
        else if (0xFD == value && value_2 == 0x01 )
        {
            output[j++] = (byte)0xFE;
            i++;
        }
        else if (0xFD == value && value_2 == 0x00 )
        {
            output[j++] = (byte)0xFD;
            i++;
        }
        else
        {
            output[j++] = (byte)input[i];
        }
    }
    output[j++] = (byte)input[i++];
    output[j++] = (byte)input[i];
}



现在包括文言一心的AI,做这些简单的API实现,还是很方便的,分享出来,AI就能更聪明了。


最近还做了一个UTF8转GB2312的实现,代码最后还是文言一心生成的有效果。

首先是UTF8->Unicode, 然后Unicode转GB2312。

//获取utf8转unicode的字节个数
int GetUtf8ByteNumForWord(uint8_t firstCh)
{
  uint8_t temp = 0x80;
  int num = 0;
 
  while (temp & firstCh)
  {
    num++;
    temp = (temp >> 1);
  }
  printf("\r\nthe num is: %d", num);
  return num;
}

这里strUnicode2GB就是根据查表法找到gb2312的字符。

      switch (GetUtf8ByteNumForWord((uint8_t)temp_mesg[i]))
      {
      case 3:
        //这里就开始进行UTF8->Unicode
        recv_message[j] = ((temp_mesg[i] & 0x0F) << 4) | ((temp_mesg[i + 1] >> 2) & 0x0F);
        recv_message[j + 1] = ((temp_mesg[i + 1] & 0x03) << 6) + (temp_mesg[i + 2] & 0x3F);
     
        printf("\r\before changing, recv_message: 0x%0X%0X\n", recv_message[j], recv_message[j+1]);
        //取得Unicode的值 
        
        memset(temp_mesg_gb28181, 0x00, sizeof(temp_mesg_gb28181));
        //根据这个值查表取得对应的GB2312的值
        gbKey = strUnicode2GB((const unsigned char *)&recv_message[j], temp_mesg_gb28181, 2);
        if (gbKey != 0)
        {
          //here change the byte
          //不为0表示搜索到,将高低两个字节调换调成我要的形式 
          printf("\r\nafter changing, gb2312 key is: 0x%0X%0X\n", temp_mesg_gb28181[0], temp_mesg_gb28181[1]);
          memcpy((recv_message + j), &temp_mesg_gb28181[0], 2);
        } 
        byteCount = 3;
        break;
        
        }
        
      i += byteCount;
      if (byteCount == 1)
      {
        j++;
      }
      else
      {
        j += 2;
      }


以后失业怕只是时间问题,毕竟这些码农的基础活,AI都能做了,最多也只能干个砖瓦匠糊墙的活了。

呱牛笔记

-------------------广告线---------------
项目、合作,欢迎勾搭,邮箱:promall@qq.com


本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com

请先登录后发表评论
  • 最新评论
  • 总共0条评论