123456789665,或許它代表著12點34分56秒789毫秒665奈秒,如果不壓縮直接傳就是 12 個 bytes,BCD 則只會有 6 個 bytes,為什麼? 說明如下:
- 一個 byte 有 8 個 bits,用來存數字,實際上只會用到後面 4 個 bits,前面的 4 個 bits 永遠為 0000,例如 5 的 8 個 bits 會是 00000101 (二進位表示法),9 的 8 bits 為 00001001。
- BCD 用一個 byte 來存兩個數字,前 4 個 bits (高位元) 存一個數字,後 4 個 bits 再存一個數字,所以,如果有兩個數字 95,用 BCD 儲存就會是 10010101,前 4 個 bits 是 9,後 4 個 bits 是 5。
底下是 BCD 的程式:
應該很容易看的懂,pack 就是將正常的資料壓縮成 BCD 格式,unpack 是將 BCD 格式的資料還原。測試程式如下:
要被壓縮的資料為 number,值為 123456789665,參考下面的輸出,可以看到 BCD 長度只有 6 bytes,其 hex 值即是我們要傳輸的值; 把 BCD 資料解壓縮,即可回 number 的值。
public class BCD { static public byte[] pack(long number) { byte hi, lo; String s = String.valueOf(number); byte[] data = s.getBytes(); byte[] bcd = new byte[s.length() / 2]; for (int i = 0; i < bcd.length; i++) { hi = (byte)(data[i * 2] << 4); lo = (byte)(data[i * 2 + 1] & 0x0f); bcd[i] = (byte)(hi | lo); } return bcd; } static public long unpack(byte[] pack, byte[] data) { byte hi, lo; long number = 0L; for (int i = 0; i < pack.length; i++) { hi = (byte)((pack[i] >> 4) & 0x0f); lo = (byte)(pack[i] & 0x0f); data[i * 2] = hi; data[i * 2 + 1] = lo; number = number * 100 + (hi * 10) + lo; } return number; } }
應該很容易看的懂,pack 就是將正常的資料壓縮成 BCD 格式,unpack 是將 BCD 格式的資料還原。測試程式如下:
要被壓縮的資料為 number,值為 123456789665,參考下面的輸出,可以看到 BCD 長度只有 6 bytes,其 hex 值即是我們要傳輸的值; 把 BCD 資料解壓縮,即可回 number 的值。
bcd len: 6
bcd value: [B@439f5b3d
bcd value (hex): 123456789665
data len: 12
data value: [B@685f4c2e
data value (hex) 010203040506070809060605
number: 123456789665
要特別注意的是,上面 unpack 程式中,高位元的資料在向左 shift 4 位到低位元後,一定要再 & 0x0f,將高位元清為 0,因為 shift 時,如果最高的 bit 為 1,往左 shift 4 位,高位的 4 個 bits 會全部變成 1,例如最前面例子舉的 95,二進位是 10010101,5 是存在低位元,只要將高位元清成0 ( & 0x0f),即可得到 5,但是 高位元的 9 向左 shift 4 位後會是 11111001,所以要將高位元再清為 0 (& 0x0f)。
沒有留言:
張貼留言