Mac CLI 完全指南:用一套命令行工具自动化管理你的 macOS 开发环境
2026/10/14 20:55:09
BCD(8421码):1个byte存2位十进制数,高4bit是十位,低4bit是个位。
例:0x12→ BCD解码 = “12”;0x59→ “59”;0x05→ “05”
/// <summary> /// BCD解码:byte[] 8421BCD 转十进制字符串 /// .NET4.8 可用 /// </summary> /// <param name="bcdBytes">BCD字节数组</param> /// <returns>十进制字符串(保留前导0)</returns> public static string BcdBytesToString(byte[] bcdBytes) { if (bcdBytes == null || bcdBytes.Length == 0) return string.Empty; char[] resultChars = new char[bcdBytes.Length * 2]; for (int i = 0; i < bcdBytes.Length; i++) { byte b = bcdBytes[i]; // 高4位 int high = (b >> 4) & 0x0F; // 低4位 int low = b & 0x0F; // 校验BCD合法性:单个4bit不能>=10 if (high >= 10 || low >= 10) { throw new FormatException($"非法BCD字节:0x{b:X2},BCD每4bit范围0~9"); } resultChars[i * 2] = (char)('0' + high); resultChars[i * 2 + 1] = (char)('0' + low); } return new string(resultChars); }byte[] bcdData = { 0x12, 0x34, 0x05 }; string str = BcdBytesToString(bcdData); Console.WriteLine(str); // 输出:123405适合BCD长度≤8字节(最多16位十进制,long上限是9223372036854775807)
public static long BcdBytesToLong(byte[] bcdBytes) { string s = BcdBytesToString(bcdBytes); if (long.TryParse(s, out long val)) return val; throw new OverflowException("BCD数值超出long范围"); }/// <summary> /// 字符串转BCD数组(8421),字符串长度必须偶数位,不足前面补0 /// </summary> public static byte[] StringToBcdBytes(string numStr) { if (numStr == null) throw new ArgumentNullException(); numStr = numStr.Trim(); if (numStr.Length % 2 != 0) numStr = "0" + numStr; // 奇数长度前面补0 byte[] bcd = new byte[numStr.Length / 2]; for (int i = 0; i < bcd.Length; i++) { char c1 = numStr[i * 2]; char c2 = numStr[i * 2 + 1]; byte high = (byte)(c1 - '0'); byte low = (byte)(c2 - '0'); bcd[i] = (byte)((high << 4) | low); } return bcd; }⚠️ 坑点:
- 有些设备BCD是小端序(字节顺序颠倒),读到byte[]后先反转数组再解码
- 有些BCD末尾带符号位,需要单独处理符号
- BCD校验:4bit的值不能是10~15,否则不是合法BCD,代码里已经抛异常
byte[] raw = {0x34,0x12}; // 设备小端BCD,实际数字1234 Array.Reverse(raw); string res = BcdBytesToString(raw); // "1234"public static string BcdBytesToStringSafe(byte[] bcdBytes) { if (bcdBytes == null || bcdBytes.Length == 0) return ""; char[] chars = new char[bcdBytes.Length * 2]; for (int i = 0; i < bcdBytes.Length; i++) { byte b = bcdBytes[i]; int h = (b >> 4) & 0x0F; int l = b & 0x0F; chars[i * 2] = h < 10 ? (char)('0' + h) : '?'; chars[i * 2 + 1] = l < 10 ? (char)('0' + l) : '?'; } return new string(chars); }你要不要我再写一个BCD转BigInteger版本,支持超过long范围的超长BCD(比如20位以上十进制)?