CRC16 MODBUS校驗(yàn)算法,分兩種情況,一是參數(shù)是字符串,二是參數(shù)是字節(jié)數(shù)組。
參考文章1
參考文章2
直接上代碼,第一種參數(shù)是字符串
public static void main(String[] args) throws IOException { String frame = "01 03 01 48 00 0c"; System.out.println(getCRC(frame)); } public static String getCRC(String data) { data = data.replace(" ", ""); int len = data.length(); if (!(len % 2 == 0)) { return "0000"; } int num = len / 2; byte[] para = new byte[num]; for (int i = 0; i < num; i++) { int value = Integer.valueOf(data.substring(i * 2, 2 * (i + 1)), 16); para[i] = (byte) value; } return getCRC(para); } /** * 計(jì)算CRC16校驗(yàn)碼 * * @param bytes * 字節(jié)數(shù)組 * @return {@link String} 校驗(yàn)碼 * @since 1.0 */ public static String getCRC(byte[] bytes) { // CRC寄存器全為1 int CRC = 0x0000ffff; // 多項(xiàng)式校驗(yàn)值 int POLYNOMIAL = 0x0000a001; int i, j; for (i = 0; i < bytes.length; i++) { CRC ^= ((int) bytes[i] & 0x000000ff); for (j = 0; j < 8; j++) { if ((CRC & 0x00000001) != 0) { CRC >>= 1; CRC ^= POLYNOMIAL; } else { CRC >>= 1; } } } // 結(jié)果轉(zhuǎn)換為16進(jìn)制 String result = Integer.toHexString(CRC).toUpperCase(); if (result.length() != 4) { StringBuffer sb = new StringBuffer("0000"); result = sb.replace(4 - result.length(), 4, result).toString(); } //高位在前地位在后 //return result.substring(2, 4) + " " + result.substring(0, 2); // 交換高低位,低位在前高位在后 return result.substring(2, 4) + " " + result.substring(0, 2); }
執(zhí)行后結(jié)果:
第二種參數(shù)是byte數(shù)組:
public static void main(String[] args) throws IOException { byte[] bytes = new byte[] { 0x01, 0x03, 0x01, 0x48, 0x00, 0x0c }; System.out.println(getCRC2(bytes)); } public static String getCRC2(byte[] bytes) { int CRC = 0x0000ffff; int POLYNOMIAL = 0x0000a001; int i, j; for (i = 0; i < bytes.length; i++) { CRC ^= (int) bytes[i]; for (j = 0; j < 8; j++) { if ((CRC & 0x00000001) == 1) { CRC >>= 1; CRC ^= POLYNOMIAL; } else { CRC >>= 1; } } } // 交換高低位,低位在前高位在后 CRC = ((CRC & 0x0000FF00) >> 8) | ((CRC & 0x000000FF) << 8); String result = Integer.toHexString(CRC); return result.substring(0, 2) + " " + result.substring(2, 4); }
運(yùn)行結(jié)果:
小菜一枚,不正確之處還請(qǐng)各位指教!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/74812.html
摘要:負(fù)責(zé)對(duì)電能檢測(cè)模塊下發(fā)收集指令,以及對(duì)電能檢測(cè)模塊響應(yīng)的數(shù)據(jù)進(jìn)行處理,一方面對(duì)接收的單相數(shù)據(jù)進(jìn)行轉(zhuǎn)換后驅(qū)動(dòng)屏幕對(duì)相關(guān)數(shù)據(jù)進(jìn)行顯示,另一方面對(duì)單相數(shù)據(jù)進(jìn)行重新打包并通過串口對(duì)以太網(wǎng)模塊進(jìn)行數(shù)據(jù)傳輸。 ...
摘要:當(dāng)主機(jī)正在從某個(gè)輸入流源源不斷地讀取文件時(shí),校驗(yàn)碼的計(jì)算是實(shí)時(shí)的,每次校驗(yàn)操作都只對(duì)文件的一部分進(jìn)行處理。在計(jì)算校驗(yàn)碼時(shí),請(qǐng)至少使用的分區(qū)大小,否則調(diào)用會(huì)造成不可忽略的時(shí)間消耗。 原文:java.util.zip.CRC32 and java.util.zip.Adler32 performance作者:Mikhail Vorontsov 校驗(yàn)碼是把任意長(zhǎng)度的字節(jié)內(nèi)容輸入通過特定算法變...
摘要:串口通信以自己剛做的功能做為核心記錄這篇博客是基于通信協(xié)議之間的通信是十六進(jìn)制進(jìn)行通信的可選波特率,數(shù)據(jù)位停止位采用校驗(yàn)功能和代碼的實(shí)現(xiàn)界面是用窗體表現(xiàn)的界面的實(shí)現(xiàn)就不過多的貼代碼和說怎么去實(shí)現(xiàn)了,有個(gè)很好用的工具,可以直接拖控件,跟做很像 串口通信以自己剛做的功能做為核心記錄這篇博客①. 是基于modbus通信協(xié)議之間的通信②. 是十六進(jìn)制進(jìn)行通信的③. 可選波特率,數(shù)據(jù)位 停止位④...
摘要:通過虛擬節(jié)點(diǎn)優(yōu)化一致性算法為了提高一致性算法的平衡性,我們首先能夠想到的是,增加節(jié)點(diǎn)數(shù),但是機(jī)器畢竟是需要經(jīng)費(fèi)啊,不是說增就能隨意增,那就增加虛擬節(jié)點(diǎn),這樣就沒毛病了。 一、案例分析(1)問題概述 假設(shè)我們的圖片數(shù)據(jù)均勻的分配在三臺(tái)服務(wù)(分別標(biāo)注為服務(wù)器A,服務(wù)器B、服務(wù)器C)上面,現(xiàn)在我們要從里面取圖片,服務(wù)端在拿到這個(gè)請(qǐng)求后,怎么會(huì)指定,這張圖片是存在服務(wù)器A、服務(wù)器B,還是服務(wù)器...
閱讀 3043·2021-09-03 10:33
閱讀 1270·2019-08-30 15:53
閱讀 2618·2019-08-30 15:45
閱讀 3379·2019-08-30 14:11
閱讀 527·2019-08-30 13:55
閱讀 2581·2019-08-29 15:24
閱讀 1906·2019-08-26 18:26
閱讀 3558·2019-08-26 13:41