在udp传输中,我们app段需要得到的是字符串,而一般发指令的设备是十六进制字符串,两者是需要通过自定义方法进行转换的,这样设备和app之间才可以通讯。
1.字符串转Byte数组
“字符串”.getBytes(“编码格式”);
2.Byte数组转字符串
String s=new String(byte数组,“编码格式”);
3.十六进制字符串转bytes数组
/**
* 十六进制字符串转bytes
*
* @param src 16进制字符串
* @return 字节数组
*/
public static byte[] hexStr2Bytes(String src) {
int l = src.length() / 2;
byte[] ret = new byte[l];
for (int i = 0; i < l; i++) {
ret[i] = (byte) Integer
.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();
}
return ret;
}
4.bytes数组转十六进制字符串
/**
* bytes转换成十六进制字符串
*
* @param b byte数组
*/
public static String Bytes2hexStr(byte[] b) {
String stmp = "";
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < b.length; i++) {
stmp = Integer.toHexString(b[i] & 0xFF);
sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
// sb.append(" ");//每个Byte值之间空格分隔
}
return sb.toString().toUpperCase().trim();
}
5.十六进制字符串转字符串
public static String hexStr2Str(String hexStr) {
return hexStr2Str(hexStr, null);
}
/**
* 16进制字符串转换为字符串
*
* @param charsetName 用于编码 String 的 Charset
*/
public static String hexStr2Str(String hexStr, String charsetName) {
hexStr = hexStr.toUpperCase();
// hexStr.replace(" ", "");
String str = "0123456789ABCDEF";
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length() / 2];
int n;
for (int i = 0; i < bytes.length; i++) {
n = str.indexOf(hexs[2 * i]) * 16;
n += str.indexOf(hexs[2 * i + 1]);
bytes[i] = (byte) (n & 0xFF);
}
String returnStr = "";// 返回的字符串
if (charsetName == null) {
// 编译器默认解码指定的 byte 数组,构造一个新的 String,
// 比如我的集成开发工具即编码器android studio的默认编码格式为"utf-8"
returnStr = new String(bytes);
} else {
// 指定的 charset 解码指定的 byte 数组,构造一个新的 String
// utf-8中文字符占三个字节,GB18030兼容GBK兼容GB2312中文字符占两个字节,ISO8859-1是拉丁字符(ASCII字符)占一个字节
try {
returnStr = new String(bytes, charsetName);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
// charset还有utf-8,gbk随需求改变
return returnStr;
}
6.字符串转十六进制字符串
public static String Str2hexStr(String str) {
return Str2hexStr(str, "");
}
/**
* 字符串转换为16进制字符串
*
* @param charsetName 用于编码 String 的 Charset
*/
public static String Str2hexStr(String str, String charsetName) {
byte[] bytes = new byte[0];
String hexString = "0123456789abcdef";
// 使用给定的 charset 将此 String 编码到 byte 序列
if (!charsetName.equals("")) {
try {
bytes = str.getBytes(charsetName);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
// 根据默认编码获取字节数组
bytes = str.getBytes();
}
StringBuilder sb = new StringBuilder(bytes.length * 2);
// 将字节数组中每个字节拆解成2位16进制整数
for (int i = 0; i < bytes.length; i++) {
sb.append(hexString.charAt((bytes[i] & 0xf0) >> 4));
sb.append(hexString.charAt((bytes[i] & 0x0f)));
}
return sb.toString();
}
7.项目里实战调用
byte[] packet = msg.getData().getByteArray(
"KEY_BYTEARRAY_RECEIVER");// 接收回来的数据
String hexStr = SmallUtil.Bytes2hexStr(packet);
// Log.d(TAG, hexStr);
String ss = SmallUtil.hexStr2Str(hexStr, "gb2312");
由于硬件发出来得信息是16进制字符串转换的byte数组,并且格式是"gb2312"所以我要将它解析才能得到我们用户能看懂的字符串。
拓展为啥要用十六进制字符串
一、原理:
Java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示(2^3+2^2+2^1+2^0=15),所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16进制字符H和L,并组合起来得到byte转换到16进制字符串的结果new String(H) + new String(L)。即byte用十六进制表示只占2位。 同理,相反的转换也是将两个16进制字符转换成一个byte,原理同上。
根据以上原理,就可以将byte数组转换为16进制字符串了,当然也可以将16进制字符串转换为byte数组了。
二 、16进制的意义:
1、用于计算机领域的一种重要的数制。
2、对计算机理论的描述,计算机硬件电路的设计都是很有益的。比如逻辑电路设计中,既要考虑功能的完备,还要考虑用尽可能少的硬件,十六进制就能起到一些理论分析的作用。比如四位二进制电路,最多就是十六种状态,也就是一种十六进制形式,只有这十六种状态都被用上了或者尽可能多的被用上,硬件资源才发挥了尽可能大的作用。
3、十六进制更简短,因为换算的时候一位16进制数可以顶4位2进制数。
Java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示(2^3+2^2+2^1+2^0=15),所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16进制字符H和L,并组合起来得到byte转换到16进制字符串的结果new String(H) + new String(L)。即byte用十六进制表示只占2位。 同理,相反的转换也是将两个16进制字符转换成一个byte,原理同上。
根据以上原理,就可以将byte数组转换为16进制字符串了,当然也可以将16进制字符串转换为byte数组了。
二 、16进制的意义:
1、用于计算机领域的一种重要的数制。
2、对计算机理论的描述,计算机硬件电路的设计都是很有益的。比如逻辑电路设计中,既要考虑功能的完备,还要考虑用尽可能少的硬件,十六进制就能起到一些理论分析的作用。比如四位二进制电路,最多就是十六种状态,也就是一种十六进制形式,只有这十六种状态都被用上了或者尽可能多的被用上,硬件资源才发挥了尽可能大的作用。
3、十六进制更简短,因为换算的时候一位16进制数可以顶4位2进制数。
拿汉字的例子来说吧
每个汉字在机器内部的机内码是唯一的
按你说的,“我”的机内码是CED2,这样的话,是要在输出的时候进行转换成汉字,输出包括屏幕和打印机输出等。
一般是按照规则将机内码转换成区位码,然后到区位码这个“表”中去查询即可。
机内码转换:CED2 转换成 十六进制区位码为 2E32
2E32每两位换成十进制的区位码就是4650
也就是说你要把区位码存在一个表中或数组中,然后用区位码进行查询,区位码就行号和列号,这样就可以输出汉字字符了。通常这个区位码表是按自己的需求,来进行优化的,因为可能不需要存所有的汉字,这个表通常叫做字模库或者字形库,都是为了输出用的。