最常用的BCD编码,就是使用"0"至"9"这十个数值的二进码来表示。这种编码方式,在称之为“8421码”(日常所说的BCD码大都是指8421BCD码形式)。除此以外,对应不同需求,各人亦开发了不同的编码方法,以适应不同的需求。这些编码,大致可以分成有权码和无权码两种:有权BCD码,如:8421(最常用)、2421、5421…
无权BCD码,如:余3码。
一个字节8位,4位表示一位数,熟悉“8421码即可。
8421码java实现如下
package util.arithmetic;
/**
* 编码工具类
* BCD与十进制的转换
*/
public class BCDDecode {
public static void main(String[] args) throws Exception {
byte[] b = str2Bcd("2213");
System.out.println(bcd2Str(b));
System.out.println(bcd2Str(new byte[]{17}));
}
/**
* 功能: BCD码转为10进制串
* 参数: BCD码
* 结果: 10进制串 byte 17->=int 11
*/
public static String bcd2Str(byte[] bytes)throws Exception {
if (bytes == null || bytes.length == 0) {
return "";
}
StringBuilder temp = new StringBuilder(bytes.length * 2);
for (byte aByte : bytes) {
byte v1 = (byte) ((aByte & 0xf0) >>> 4);
temp.append(v1);
byte v2 = (byte) (aByte & 0x0f);
temp.append(v2);
if (v1 > 9 || v2 > 9) {
//不是bcd码舍去
throw new Exception("非BCD编码");
}
}
return temp.substring(0, 1).equalsIgnoreCase("0") ? temp.substring(1) : temp.toString();
}
/**
* 十进制字符串转BCD码。举例:
* 如果十进制字符串为"2",转换后的BCD码为00000010
* 如果十进制字符串为"12",转换后的BCD码为00010010
* 如果十进制字符串为"123",转换后的BCD码为00000001 00100011
*
* @param decStr 十进制字符串
* @return BCD码
* @throws Exception
*/
public static byte[] str2Bcd(String decStr) throws Exception {
// 因为可能修改字符串的内容,所以构造StringBuffer
StringBuffer sb = new StringBuffer(decStr);
// 一个字节包含两个4位的BCD码,byte数组中要包含偶数个BCD码
// 一个十进制字符对应4位BCD码,所以如果十进制字符串的长度是奇数,要在前面补一个0使长度成为偶数
if ((sb.length() % 2) != 0) {
sb.insert(0, '0');
}
// 两个十进制数字转换为BCD码后占用一个字节,所以存放BCD码的字节数等于十进制字符串长度的一半
byte[] bcd = new byte[sb.length() / 2];
for (int i = 0; i < sb.length(); ) {
if (!Character.isDigit(sb.charAt(i)) || !Character.isDigit(sb.charAt(i + 1))) {
throw new Exception("传入的十进制字符串包含非数字字符!");
}
// 每个字节的构成:用两位十进制数字运算的和填充,高位十进制数字左移4位+低位十进制数字
bcd[i / 2] = (byte) ((Character.digit(sb.charAt(i), 10) << 4) + Character.digit(sb.charAt(i + 1), 10));
// 字符串的每两个字符取出来一起处理,所以此处i的自增长要加2,而不是加1
i += 2;
}
return bcd;
}
/**
* 功能: 10进制串转为BCD码
* 参数: 10进制串
* 结果: BCD码
*/
public static byte[] str2BcdExtend(String asc) {
int len = asc.length();
int mod = len % 2;
if (mod != 0) {
asc = "0" + asc;
len = asc.length();
}
//byte[] abt = new byte[len];
if (len >= 2) {
len = len / 2;
}
byte[] bbt = new byte[len];
byte[] abt = asc.getBytes();
int j, k;
for (int p = 0; p < asc.length() / 2; p++) {
if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
j = abt[2 * p] - '0';
} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
j = abt[2 * p] - 'a' + 0x0a;
} else {
j = abt[2 * p] - 'A' + 0x0a;
}
if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
k = abt[2 * p + 1] - '0';
} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
k = abt[2 * p + 1] - 'a' + 0x0a;
} else {
k = abt[2 * p + 1] - 'A' + 0x0a;
}
int a = (j << 4) + k;
byte b = (byte) a;
bbt[p] = b;
}
return bbt;
}
}