zl程序教程

您现在的位置是:首页 >  后端

当前栏目

JAVA十六进制与字符串的转换

JAVA转换 字符串 十六进制
2023-06-13 09:14:09 时间

笔者前几日在开服过程中需要将字符串转化成为16进制的字符串,在网上找到了一些方法尝试之后,均发现存在一个问题-->字符串转为16进制后再转回来,英文正常,中文出现乱码

经过考虑决定通过以下方式进行解决: 

  1)在将字符串转为16进制之前先进行一次转化,先将其转化成为Unicode编码(相当于把中文用英文字符代替),在转化成为16进制

  2)相反的,在十六进制转换为字符串后的得到的是Unicode编码,此时再将Unicode编码解码即可获取原始字符串

代码如下:

/**
*字符串转换unicode
*/
publicstaticStringstring2Unicode(Stringstring){
  StringBufferunicode=newStringBuffer();
  for(inti=0;i<string.length();i++){
    //取出每一个字符
charc=string.charAt(i);
//转换为unicode
unicode.append("\\u"+Integer.toHexString(c));
  }
  returnunicode.toString();
}

*字符串转为16进制

/**
*字符串转化成为16进制字符串
*@params
*@return
*/
publicstaticStringstrTo16(Strings){
Stringstr="";
for(inti=0;i<s.length();i++){
intch=(int)s.charAt(i);
Strings4=Integer.toHexString(ch);
str=str+s4;
}
returnstr;
}

*16进制转为字符串

/**
*16进制转换成为string类型字符串
*@params
*@return
*/
publicstaticStringhexStringToString(Strings){
if(s==null||s.equals("")){
returnnull;
}
s=s.replace("","");
byte[]baKeyword=newbyte[s.length()/2];
for(inti=0;i<baKeyword.length;i++){
try{
baKeyword[i]=(byte)(0xff&Integer.parseInt(s.substring(i*2,i*2+2),16));
}catch(Exceptione){
e.printStackTrace();
}
}
try{
s=newString(baKeyword,"UTF-8");
newString();
}catch(Exceptione1){
e1.printStackTrace();
}
returns;
}

*Unicode转为字符串

/**
*unicode转字符串
*/
publicstaticStringunicode2String(Stringunicode){
StringBufferstring=newStringBuffer();
String[]hex=unicode.split("\\\\u");
for(inti=1;i<hex.length;i++){
//转换出每一个代码点
intdata=Integer.parseInt(hex[i],16);
//追加成string
string.append((char)data);
}
returnstring.toString();
}

此方法虽然解决了转化过程中中文乱码的问题,但是过于复杂,笔者后来又发现一种新的转化方式,可直接转化,中文不乱码,

代码如下:

*字符串转16进制

/**
*字符串转换成为16进制(无需Unicode编码)
*@paramstr
*@return
*/
publicstaticStringstr2HexStr(Stringstr){
char[]chars="0123456789ABCDEF".toCharArray();
StringBuildersb=newStringBuilder("");
byte[]bs=str.getBytes();
intbit;
for(inti=0;i<bs.length;i++){
bit=(bs[i]&0x0f0)>>4;
sb.append(chars[bit]);
bit=bs[i]&0x0f;
sb.append(chars[bit]);
//sb.append("");
}
returnsb.toString().trim();
}

*16进制转为字符串

/**
*16进制直接转换成为字符串(无需Unicode解码)
*@paramhexStr
*@return
*/
publicstaticStringhexStr2Str(StringhexStr){
Stringstr="0123456789ABCDEF";
char[]hexs=hexStr.toCharArray();
byte[]bytes=newbyte[hexStr.length()/2];
intn;
for(inti=0;i<bytes.length;i++){
n=str.indexOf(hexs[2*i])*16;
n+=str.indexOf(hexs[2*i+1]);
bytes[i]=(byte)(n&0xff);
}
returnnewString(bytes);
}

下面是补充

java字符串和十六进制字符串互转

publicclassHexStringUtils{

privatestaticfinalchar[]DIGITS_HEX={"0","1","2","3","4","5","6","7","8","9","A","B","C","D",
"E","F"};

protectedstaticchar[]encodeHex(byte[]data){
intl=data.length;
char[]out=newchar[l<<1];
for(inti=0,j=0;i<l;i++){
out[j++]=DIGITS_HEX[(0xF0&data[i])>>>4];
out[j++]=DIGITS_HEX[0x0F&data[i]];
}
returnout;
}

protectedstaticbyte[]decodeHex(char[]data){
intlen=data.length;
if((len&0x01)!=0){
thrownewRuntimeException("字符个数应该为偶数");
}
byte[]out=newbyte[len>>1];
for(inti=0,j=0;j<len;i++){
intf=toDigit(data[j],j)<<4;
j++;
f|=toDigit(data[j],j);
j++;
out[i]=(byte)(f&0xFF);
}
returnout;
}

protectedstaticinttoDigit(charch,intindex){
intdigit=Character.digit(ch,16);
if(digit==-1){
thrownewRuntimeException("Illegalhexadecimalcharacter"+ch+"atindex"+index);
}
returndigit;
}

publicstaticStringtoHex(Stringstr){
returnnewString(encodeHex(str.getBytes()));
}

publicstaticStringfromHex(Stringhex){
returnnewString(decodeHex(hex.toCharArray()));
}

publicstaticvoidmain(String[]args){
Strings="abc你好";
Stringhex=toHex(s);
Stringdecode=fromHex(hex);
System.out.println("原字符串:"+s);
System.out.println("十六进制字符串:"+hex);
System.out.println("还原:"+decode);
}
}

toHexString

publicstaticStringtoHexString(inti)以十六进制的无符号整数形式返回一个整数参数的字符串表示形式。
如果参数为负,那么无符号整数值为参数加上232;否则等于该参数。将该值转换为十六进制(基数16)的无前导0的ASCII数字字符串。如果无符号数的大小值为零,则用一个零字符"0"("\u0030")表示它;否则,无符号数大小的表示形式中的第一个字符将不是零字符。用以下字符作为十六进制数字:

0123456789abcdef

这些字符的范围是从"\u0030"到"\u0039"和从"\u0061"到"\u0066"。如果希望得到大写字母,可以在结果上调用String.toUpperCase()方法:

Integer.toHexString(n).toUpperCase()

参数:
i-要转换成字符串的整数。

返回:

用十六进制(基数16)参数表示的无符号整数值的字符串表示形式。

//转化字符串为十六进制编码
publicstaticStringtoHexString(Strings)
{
Stringstr="";
for(inti=0;i<s.length();i++)
{
intch=(int)s.charAt(i);
Strings4=Integer.toHexString(ch);
str=str+s4;
}
returnstr;
}
//转化十六进制编码为字符串
publicstaticStringtoStringHex(Strings)
{
byte[]baKeyword=newbyte[s.length()/2];
for(inti=0;i<baKeyword.length;i++)
{
try
{
baKeyword[i]=(byte)(0xff&Integer.parseInt(s.substring(i*2,i*2+2),16));
}
catch(Exceptione)
{
e.printStackTrace();
}
}
try
{
s=newString(baKeyword,"utf-8");//UTF-16le:Not
}
catch(Exceptione1)
{
e1.printStackTrace();
}
returns;
}
//转化十六进制编码为字符串
publicstaticStringtoStringHex(Strings)
{
byte[]baKeyword=newbyte[s.length()/2];
for(inti=0;i<baKeyword.length;i++)
{
try
{
baKeyword[i]=(byte)(0xff&Integer.parseInt(s.substring(i*2,i*2+2),16));
}
catch(Exceptione)
{
e.printStackTrace();
}
}
try
{
s=newString(baKeyword,"utf-8");//UTF-16le:Not
}
catch(Exceptione1)
{
e1.printStackTrace();
}
returns;
}
publicstaticvoidmain(String[]args){
System.out.println(encode("中文"));
System.out.println(decode(encode("中文")));
}
/*
*16进制数字字符集
*/
privatestaticStringhexString="0123456789ABCDEF";
/*
*将字符串编码成16进制数字,适用于所有字符(包括中文)
*/
publicstaticStringencode(Stringstr)
{
//根据默认编码获取字节数组
byte[]bytes=str.getBytes();
StringBuildersb=newStringBuilder(bytes.length*2);
//将字节数组中每个字节拆解成2位16进制整数
for(inti=0;i<bytes.length;i++)
{
sb.append(hexString.charAt((bytes[i]&0xf0)>>4));
sb.append(hexString.charAt((bytes[i]&0x0f)>>0));
}
returnsb.toString();
}
/*
*将16进制数字解码成字符串,适用于所有字符(包括中文)
*/
publicstaticStringdecode(Stringbytes)
{
ByteArrayOutputStreambaos=newByteArrayOutputStream(bytes.length()/2);
//将每2位16进制整数组装成一个字节
for(inti=0;i<bytes.length();i+=2)
baos.write((hexString.indexOf(bytes.charAt(i))<<4|hexString.indexOf(bytes.charAt(i+1))));
returnnewString(baos.toByteArray());
}

第二种方法:

将指定byte数组以16进制的形式打印到控制台

packagecom.nantian.iclient.atm.sdb;

publicclassUtil{
publicUtil(){
}

/**
*将指定byte数组以16进制的形式打印到控制台
*@paramhintString
*@parambbyte[]
*@returnvoid
*/
publicstaticvoidprintHexString(Stringhint,byte[]b){
System.out.print(hint);
for(inti=0;i<b.length;i++){
Stringhex=Integer.toHexString(b[i]&0xFF);
if(hex.length()==1){
hex="0"+hex;
}
System.out.print(hex.toUpperCase()+"");
}
System.out.println("");
}

/**
*
*@parambbyte[]
*@returnString
*/
publicstaticStringBytes2HexString(byte[]b){
Stringret="";
for(inti=0;i<b.length;i++){
Stringhex=Integer.toHexString(b[i]&0xFF);
if(hex.length()==1){
hex="0"+hex;
}
ret+=hex.toUpperCase();
}
returnret;
}

/**
*将两个ASCII字符合成一个字节;
*如:"EF"-->0xEF
*@paramsrc0byte
*@paramsrc1byte
*@returnbyte
*/
publicstaticbyteuniteBytes(bytesrc0,bytesrc1){
byte_b0=Byte.decode("0x"+newString(newbyte[]{src0})).byteValue();
_b0=(byte)(_b0<<4);
byte_b1=Byte.decode("0x"+newString(newbyte[]{src1})).byteValue();
byteret=(byte)(_b0^_b1);
returnret;
}

/**
*将指定字符串src,以每两个字符分割转换为16进制形式
*如:"2B44EFD9"-->byte[]{0x2B,0x44,0xEF,0xD9}
*@paramsrcString
*@returnbyte[]
*/
publicstaticbyte[]HexString2Bytes(Stringsrc){
byte[]ret=newbyte[8];
byte[]tmp=src.getBytes();
for(inti=0;i<8;i++){
ret[i]=uniteBytes(tmp[i*2],tmp[i*2+1]);
}
returnret;
}

}