java 案例CMD指令 byte CRC4、CRC5篱昔、CRC6每强、CRC7、CRC8旱爆、CRC16舀射、CRC32、LRC怀伦、BBC脆烟、byte與String互轉(zhuǎn)(CMD)

CRC(循環(huán)冗余校驗(yàn))在線計(jì)算:
http://www.ip33.com/crc.html
LRC校驗(yàn)(縱向冗余校驗(yàn))在線計(jì)算:
http://www.ip33.com/lrc.html
BCC校驗(yàn)(異或校驗(yàn))在線計(jì)算:
http://www.ip33.com/bcc.html
CRC校驗(yàn)(循環(huán)冗余校驗(yàn))小知識(shí)
CRC即循環(huán)冗余校驗(yàn)碼(Cyclic Redundancy Check):是數(shù)據(jù)通信領(lǐng)域中最常用的一種查錯(cuò)校驗(yàn)碼,其特征是信息字段和校驗(yàn)字段的長(zhǎng)度可以任意選定。循環(huán)冗余檢查(CRC)是一種數(shù)據(jù)傳輸檢錯(cuò)功能,對(duì)數(shù)據(jù)進(jìn)行多項(xiàng)式計(jì)算页响,并將得到的結(jié)果附在幀的后面肋层,接收設(shè)備也執(zhí)行類似的算法,以保證數(shù)據(jù)傳輸?shù)恼_性和完整性渔伯。

  • CRC算法參數(shù)模型解釋:
    NAME:參數(shù)模型名稱。
    WIDTH:寬度,即CRC比特?cái)?shù)敏簿。
    POLY:生成項(xiàng)的簡(jiǎn)寫,以16進(jìn)制表示。例如:CRC-32即是0x04C11DB7惯裕,忽略了最高位的"1"温数,即完整的生成項(xiàng)是0x104C11DB7。
    INIT:這是算法開始時(shí)寄存器(crc)的初始化預(yù)置值蜻势,十六進(jìn)制表示撑刺。
    REFIN:待測(cè)數(shù)據(jù)的每個(gè)字節(jié)是否按位反轉(zhuǎn),True或False握玛。
    REFOUT:在計(jì)算后之后够傍,異或輸出之前,整個(gè)數(shù)據(jù)是否按位反轉(zhuǎn)挠铲,True或False冕屯。
    XOROUT:計(jì)算結(jié)果與此參數(shù)異或后得到最終的CRC值。

常見CRC參數(shù)模型如下:

CRC算法名稱 多項(xiàng)式公式 寬度 多項(xiàng)式 初始值 結(jié)果異或值 輸入反轉(zhuǎn) 輸出反轉(zhuǎn)
CRC-4/ITU x4 + x + 1 4 03 00 00 true true
CRC-5/EPC x5 + x3 + 1 5 09 09 00 false false
CRC-5/ITU x5 + x4 + x2 + 1 5 15 00 00 true true
CRC-5/USB x5 + x2 + 1 5 05 1F 1F true true
CRC-6/ITU x6 + x + 1 6 03 00 00 true true
CRC-7/MMC x7 + x3 + 1 7 09 00 00 false false
CRC-8 x8 + x2 + x + 1 8 07 00 00 false false
CRC-8/ITU x8 + x2 + x + 1 8 07 00 55 false false
CRC-8/ROHC x8 + x2 + x + 1 8 07 FF 00 true true
CRC-8/MAXIM x8 + x5 + x4 + 1 8 31 00 00 true true
CRC-16/IBM x16 + x15 + x2 + 1 16 8005 0000 0000 true true
CRC-16/MAXIM x16 + x15 + x2 + 1 16 8005 0000 FFFF true true
CRC-16/USB x16 + x15 + x2 + 1 16 8005 FFFF FFFF true true
CRC-16/MODBUS x16 + x15 + x2 + 1 16 8005 FFFF 0000 true true
CRC-16/CCITT x16 + x12 + x5 + 1 16 1021 0000 0000 true true
CRC-16/CCITT-FALSE x16 + x12 + x5 + 1 16 1021 FFFF 0000 false false
CRC-16/X25 x16 + x12 + x5 + 1 16 1021 FFFF FFFF true true
CRC-16/XMODEM x16 + x12 + x5 + 1 16 1021 0000 0000 false false
CRC-16/DNP x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1 16 3D65 0000 FFFF true true
CRC-32 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 32 04C11DB7 FFFFFFFF FFFFFFFF true true
CRC-32/MPEG-2 x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 32 04C11DB7 FFFFFFFF 00000000 false false

案例一:

指令說明
image.png
指令
image.png

案例二:

指令說明
image.png
指令
image.png

image.png

image.png

CRC8

使用列子

byte[] data = new byte[8];
data[0] = (byte) 0xA5;
data[1] = (byte) 0x01;
data[2] = (byte) ~0x01;
data[3] = (byte) 0x00;
data[4] = (byte) seqNo;
data[5] = (byte) 0;
data[6] = (byte) 0;
data[7] = BleCRC.calCRC8(data);
public class BleCRC {
    /**
     * CRC8 code table
     */
    private static final char[] Table_CRC8 = { 0x00, 0x07, 0x0E, 0x09, 0x1C,
            0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
            0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46,
            0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB,
            0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, 0x90,
            0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
            0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5,
            0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0,
            0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93,
            0x94, 0x9D, 0x9A, 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
            0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59,
            0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74,
            0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1,
            0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, 0xF9, 0xFE, 0xF7, 0xF0,
            0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3,
            0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56,
            0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, 0x05,
            0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
            0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78,
            0x7F, 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25,
            0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE,
            0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F,
            0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC,
            0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 };

    /**
     * Generate CRC8 code
     * @param buf Data buffer
     * @return CRC8 code, return 0 when the parameter is error
     */
    public static byte calCRC8(byte[] buf) {
        if (buf == null || buf.length == 0) {
            return 0;
        }

        byte crc = 0;

        for (int i = 0; i < buf.length-1; i++) {
            crc = (byte)Table_CRC8[0x00ff & (crc ^ (buf[i]))];
        }
        return crc;
    }
}

LRC

使用列子

byte[] data = new byte[8];
data[0] = (byte) 0xA5;
data[1] = (byte) 0x01;
data[2] = (byte) ~0x01;
data[3] = (byte) 0x00;
data[4] = (byte) seqNo;
data[5] = (byte) 0;
data[6] = (byte) 0;
data[7] = BleCRC.getLRC(data);
//或者
byte[] data = new byte[8];
data[0] = (byte) 0xA5;
data[1] = (byte) 0x01;
data[2] = (byte) ~0x01;
data[3] = (byte) 0x00;
data[4] = (byte) seqNo;
data[5] = (byte) 0;
data[6] = (byte) 0;
data[7] =  (byte) (bytes[0] ^ bytes[1] ^ bytes[2] ^ bytes[3] ^ bytes[4] ^ bytes[5] ^ bytes[6] ^ bytes[7];
/*
* 輸入byte[] data , 返回LRC校驗(yàn)byte
*/
public static byte getLRC(byte[] data) {
  int tmp = 0;
  for (int i = 0; i < data.length; i++) {
    tmp = tmp + (byte) data[i];
  }
  tmp = ~tmp;
  tmp = (tmp & (0xff));
   tmp += 1;
    return (byte) tmp;
}

CRC16

public class CRC16Util {
    /**
     * 將int轉(zhuǎn)換成byte數(shù)組市殷,低位在前愕撰,高位在后
     * 改變高低位順序只需調(diào)換數(shù)組序號(hào)
     */
    private static byte[] intToBytes(int value) {
        byte[] src = new byte[2];
        src[1] = (byte) ((value >> 8) & 0xFF);
        src[0] = (byte) (value & 0xFF);
        return src;
    }

    /**
     * 獲取源數(shù)據(jù)和驗(yàn)證碼的組合byte數(shù)組
     *
     * @param strings 可變長(zhǎng)度的十六進(jìn)制字符串
     * @return
     */
    public static byte[] appendCrc16(String... strings) {
        byte[] data = new byte[]{};
        for (int i = 0; i < strings.length; i++) {
            int x = Integer.parseInt(strings[i], 16);
            byte n = (byte) x;
            byte[] buffer = new byte[data.length + 1];
            byte[] aa = {n};
            System.arraycopy(data, 0, buffer, 0, data.length);
            System.arraycopy(aa, 0, buffer, data.length, aa.length);
            data = buffer;
        }
        return appendCrc16(data);
    }

    /**
     * 獲取源數(shù)據(jù)和驗(yàn)證碼的組合byte數(shù)組
     *
     * @param aa 字節(jié)數(shù)組
     * @return
     */
    public static byte[] appendCrc16(byte[] aa) {
        byte[] bb = getCrc16(aa);
        byte[] cc = new byte[aa.length + bb.length];
        System.arraycopy(aa, 0, cc, 0, aa.length);
        System.arraycopy(bb, 0, cc, aa.length, bb.length);
        return cc;
    }

    /**
     * 獲取驗(yàn)證碼byte數(shù)組,基于Modbus CRC16的校驗(yàn)算法
     */
    public static byte[] getCrc16(byte[] arr_buff) {
        int len = arr_buff.length;

        // 預(yù)置 1 個(gè) 16 位的寄存器為十六進(jìn)制FFFF, 稱此寄存器為 CRC寄存器醋寝。
        int crc = 0xFFFF;
        int i, j;
        for (i = 0; i < len; i++) {
            // 把第一個(gè) 8 位二進(jìn)制數(shù)據(jù) 與 16 位的 CRC寄存器的低 8 位相異或, 把結(jié)果放于 CRC寄存器
            crc = ((crc & 0xFF00) | (crc & 0x00FF) ^ (arr_buff[i] & 0xFF));
            for (j = 0; j < 8; j++) {
                // 把 CRC 寄存器的內(nèi)容右移一位( 朝低位)用 0 填補(bǔ)最高位, 并檢查右移后的移出位
                if ((crc & 0x0001) > 0) {
                    // 如果移出位為 1, CRC寄存器與多項(xiàng)式A001進(jìn)行異或
                    crc = crc >> 1;
                    crc = crc ^ 0xA001;
                } else
                    // 如果移出位為 0,再次右移一位
                    crc = crc >> 1;
            }
        }
        return intToBytes(crc);
    }
}

byte與String互轉(zhuǎn)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BytesHexStrTranslate {

 public static void main(String[] args) throws Exception {
        byte[] bytes = "測(cè)試".getBytes("utf-8");
        System.out.println("字節(jié)數(shù)組為:" + Arrays.toString(bytes));
        System.out.println("方法一:" + bytesToHexFun1(bytes));
        System.out.println("方法二:" + bytesToHexFun2(bytes));
        System.out.println("方法三:" + bytesToHexFun3(bytes));

        System.out.println("==================================");

        String str = "e6b58be8af95";
        System.out.println("轉(zhuǎn)換后的字節(jié)數(shù)組:" + Arrays.toString(toBytes(str)));
        System.out.println(new String(toBytes(str), "utf-8"));
    }

    /**
     * 把十六進(jìn)制字符串轉(zhuǎn)成字符數(shù)組
     * @param value
     * @return
     */
    public static List<String> stringToStrZu(String value) {
        List<String> deviceValue = new ArrayList<>();
        int count = value.length();
        int index = 0;
        int end = 2;
        while (count > 0) {
            deviceValue.add(value.substring(index, end));
            index += 2;
            end += 2;
            count -= 2;
        }
        return deviceValue;
    }

    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', 
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 方法一:
     * byte[] to hex string
     * 
     * @param bytes
     * @return
     */
    public static String bytesToHexFun1(byte[] bytes) {
        // 一個(gè)byte為8位搞挣,可用兩個(gè)十六進(jìn)制位標(biāo)識(shí)
        char[] buf = new char[bytes.length * 2];
        int a = 0;
        int index = 0;
        for(byte b : bytes) { // 使用除與取余進(jìn)行轉(zhuǎn)換
            if(b < 0) {
                a = 256 + b;
            } else {
                a = b;
            }

            buf[index++] = HEX_CHAR[a / 16];
            buf[index++] = HEX_CHAR[a % 16];
        }

        return new String(buf);
    }

    /**
     * 方法二:
     * byte[] to hex string
     * 
     * @param bytes
     * @return
     */
    public static String bytesToHexFun2(byte[] bytes) {
        char[] buf = new char[bytes.length * 2];
        int index = 0;
        for(byte b : bytes) { // 利用位運(yùn)算進(jìn)行轉(zhuǎn)換,可以看作方法一的變種
            buf[index++] = HEX_CHAR[b >>> 4 & 0xf];
            buf[index++] = HEX_CHAR[b & 0xf];
        }

        return new String(buf);
    }

    /**
     * 方法三:
     * byte[] to hex string
     * 
     * @param bytes
     * @return
     */
    public static String bytesToHexFun3(byte[] bytes) {
        StringBuilder buf = new StringBuilder(bytes.length * 2);
        for(byte b : bytes) { // 使用String的format方法進(jìn)行轉(zhuǎn)換
            buf.append(String.format("%02x", new Integer(b & 0xff)));
        }

        return buf.toString();
    }

    /**
     * 將16進(jìn)制字符串轉(zhuǎn)換為byte[]
     * 
     * @param str
     * @return
     */
    public static byte[] toBytes(String str) {
        if(str == null || str.trim().equals("")) {
            return new byte[0];
        }

        byte[] bytes = new byte[str.length() / 2];
        for(int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }

        return bytes;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末音羞,一起剝皮案震驚了整個(gè)濱河市囱桨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗅绰,老刑警劉巖舍肠,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窘面,居然都是意外死亡翠语,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門财边,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肌括,“玉大人,你說我怎么就攤上這事酣难〉玻” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵憨募,是天一觀的道長(zhǎng)紧索。 經(jīng)常有香客問我,道長(zhǎng)菜谣,這世上最難降的妖魔是什么珠漂? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任晚缩,我火速辦了婚禮,結(jié)果婚禮上媳危,老公的妹妹穿的比我還像新娘橡羞。我一直安慰自己,他們只是感情好济舆,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著莺债,像睡著了一般滋觉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上齐邦,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天椎侠,我揣著相機(jī)與錄音,去河邊找鬼措拇。 笑死我纪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丐吓。 我是一名探鬼主播浅悉,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼券犁!你這毒婦竟也來了术健?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤粘衬,失蹤者是張志新(化名)和其女友劉穎荞估,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體稚新,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡勘伺,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了褂删。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片飞醉。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖笤妙,靈堂內(nèi)的尸體忽然破棺而出冒掌,到底是詐尸還是另有隱情,我是刑警寧澤蹲盘,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布股毫,位于F島的核電站,受9級(jí)特大地震影響召衔,放射性物質(zhì)發(fā)生泄漏铃诬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望趣席。 院中可真熱鬧兵志,春花似錦、人聲如沸宣肚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽霉涨。三九已至按价,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間笙瑟,已是汗流浹背楼镐。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留往枷,地道東北人框产。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像错洁,于是被迫代替她去往敵國(guó)和親秉宿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容