te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>communication - Reverse engineer a CRC or checksum - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

communication - Reverse engineer a CRC or checksum - Stack Overflow

programmeradmin4浏览0评论

I would like some help with figuring out the crc byte of a RS485 communication of an Endress+Hauser pH probe

I have here init bytes of 4 different probes, the first byte i'm not so sure if it is included, its more like an start of frame that pulls the line low for 1120us.

The sixth byte (0x1F) is xor of the first bytes, 9th byte is also xor of 7th and 8th byte

0x00 0x01 0x1A 0x04 0x00 0x1F 0x22 0x04 0x26 0x80
0x00 0x01 0x1A 0x04 0x00 0x1F 0x29 0xE9 0xC0 0x77
0x00 0x01 0x1A 0x04 0x00 0x1F 0x52 0xA8 0xFA 0x18
0x00 0x01 0x1A 0x04 0x00 0x1F 0x6B 0x5F 0x34 0x13

Only the last byte puzzles me. Can't find how that gets calculated

EDIT: The system is an Endress+Hauser pH measuring device. The meter is LIQUISYS-H and the probes are CPS11D-7FA21. The system uses digital communication between the probe and instrument and inductive couping to prevent corrosion. I went so far to successfuly read the probe (mV and temperature) but my system works as long as I don't change the probe with a new one. What you are seeing here is a part of a lenghty initialization of the probe at start (calibatrion data is read and probe identified), but the snippet I pasted is some kind of init code that "wakes up" the probe for reading. In other words if you power up the probe you need to send one of these bytes to it one time and then just poll the probe with

0x00 0x01 0x01 0x01 0x00 0x01

over and over to get the mV and temperature responses. Every probe has different init codes that I have yet not identified but first I need to get all of these checksums or crc figured out. Thank you

I would like some help with figuring out the crc byte of a RS485 communication of an Endress+Hauser pH probe

I have here init bytes of 4 different probes, the first byte i'm not so sure if it is included, its more like an start of frame that pulls the line low for 1120us.

The sixth byte (0x1F) is xor of the first bytes, 9th byte is also xor of 7th and 8th byte

0x00 0x01 0x1A 0x04 0x00 0x1F 0x22 0x04 0x26 0x80
0x00 0x01 0x1A 0x04 0x00 0x1F 0x29 0xE9 0xC0 0x77
0x00 0x01 0x1A 0x04 0x00 0x1F 0x52 0xA8 0xFA 0x18
0x00 0x01 0x1A 0x04 0x00 0x1F 0x6B 0x5F 0x34 0x13

Only the last byte puzzles me. Can't find how that gets calculated

EDIT: The system is an Endress+Hauser pH measuring device. The meter is LIQUISYS-H and the probes are CPS11D-7FA21. The system uses digital communication between the probe and instrument and inductive couping to prevent corrosion. I went so far to successfuly read the probe (mV and temperature) but my system works as long as I don't change the probe with a new one. What you are seeing here is a part of a lenghty initialization of the probe at start (calibatrion data is read and probe identified), but the snippet I pasted is some kind of init code that "wakes up" the probe for reading. In other words if you power up the probe you need to send one of these bytes to it one time and then just poll the probe with

0x00 0x01 0x01 0x01 0x00 0x01

over and over to get the mV and temperature responses. Every probe has different init codes that I have yet not identified but first I need to get all of these checksums or crc figured out. Thank you

Share Improve this question edited 2 days ago TadyTheFish asked 2 days ago TadyTheFishTadyTheFish 33 bronze badges 3
  • It is impossible to tell what is really happening with the information you gave. Please update your post with more context. Mainly, what is the exact model of your pH meter and what those bytes exactly stand for (answer of which requests) ? – jlandercy Commented 2 days ago
  • 2 Have you asked the manufacturer for details of the protocol? This does not seem like the sort of cheap consumer-grade device you would need to reverse engineer. – Sneftel Commented 2 days ago
  • This question is similar to: Memosense pH probe communication CRC reverse engeneering. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – Mark Adler Commented 2 days ago
Add a comment  | 

1 Answer 1

Reset to default 0

Your class of sensor seems to implement a CRC checksum on the complete payload but does not provide any information on the actual CRC setup.

If you believe your initialization datagrams do contain a checksum then your problem is equivalent to find out which CRC setup (polynomial, init, xorout) has been chosen to check the payload.

CRC32 is 4 bytes long which is incompatible with your setup as the first six bytes over the ten are identical (therefore they must have the same CRC32, same last four bytes).

It could be some CRC16 (which is 2 bytes long) or CRC8 (which is 1 byte long) but does not seems to be standard CRC as you can see below.

Here is some code to check out the result:

from collections.abc import Callable
import crcmod

crc8 = crcmod.mkCrcFun(0x107, rev=False, initCrc=0x00, xorOut=0x00)
crc16 = crcmod.mkCrcFun(0x18005, rev=False, initCrc=0xffff, xorOut=0x0000)
crc32 = crcmod.mkCrcFun(poly=0x104c11db7, rev=True, initCrc=0x00000000, xorOut=0xffffffff)

datagrams = [
    b"\x00\x01\x1A\x04\x00\x1F\x22\x04\x26\x80",
    b"\x00\x01\x1A\x04\x00\x1F\x29\xE9\xC0\x77",
    b"\x00\x01\x1A\x04\x00\x1F\x52\xA8\xFA\x18",
    b"\x00\x01\x1A\x04\x00\x1F\x6B\x5F\x34\x13",
]

def checksum(payload: bytes, method: Callable = crc32, size: int = 4, order: str = "big") -> bytes:
    return method(payload).to_bytes(size, order)

for method, size in [(crc8, 1), (crc16, 2), (crc32, 4)]:
    checksums = [checksum(datagram[:-size], method=method, size=size) for datagram in datagrams]
    trials = [datagram[-size:] for datagram in datagrams]
    checked = checksum == trials
    print(f"{checked}: {trials} {checksums}")

# False: [b'\x80', b'w', b'\x18', b'\x13'] [b'\xb1', b'K', b'(', b'\xe8']
# False: [b'&\x80', b'\xc0w', b'\xfa\x18', b'4\x13'] [b'\x7f\xac', b'\xc7\xc1', b'\\B', b'Hs']
# False: [b'"\x04&\x80', b')\xe9\xc0w', b'R\xa8\xfa\x18', b'k_4\x13'] [b'9\x07\x9a\xc1', b'9\x07\x9a\xc1', b'9\x07\x9a\xc1', b'9\x07\x9a\xc1']

Now, if your datagram does contain the checksum, the task is about to find out which CRC setup is implemented in your system.

You may check this List of CRC values to find out the rigth setup.

发布评论

评论列表(0)

  1. 暂无评论