nearlink_sdr.common.crc 源代码
__all__ = [
"CRC12_POLY",
"CRC24A_POLY",
"CRC24B_POLY",
"CRC32_POLY",
"crc_attach",
"crc_calculate",
"crc_check",
]
import numpy as np
try:
from nearlink_sdr_accel import rust_crc_calculate as _rust_crc
_HAS_RUST_CRC = True
except ImportError:
_HAS_RUST_CRC = False
# TXS-10002-2025 6.10.1 循环冗余校验
# 标准定义的CRC生成多项式(用比特位表示,高位在前)
# CRC12: D^12 + D^11 + D^3 + D^2 + D + 1
CRC12_POLY = 0x80F
# CRC24A: D^24 + D^10 + D^9 + D^6 + D^4 + D^3 + D + 1
CRC24A_POLY = 0x00065B
# CRC24B: D^24 + D^23 + D^21 + D^20 + D^17 + D^15 + D^13 + D^12 + D^8 + D^4 + D^2 + D + 1
CRC24B_POLY = 0xB2B117
# CRC32: D^32 + D^26 + D^23 + D^22 + D^16 + D^12 + D^11 + D^10 + D^8 + D^7 + D^5 + D^4 + D^2 + D + 1
CRC32_POLY = 0x04C11DB7
[文档]
def crc_calculate(data_bits: np.ndarray, poly: int, crc_len: int,
seed: int = 0) -> np.ndarray:
"""按照 TXS-10002-2025 6.10.1 计算循环冗余校验。
:param data_bits: 输入信息比特序列, shape (A,), 值为 0/1
:param poly: CRC生成多项式(不含最高位 D^L)
:param crc_len: 校验比特长度 L
:param seed: CRC生成种子
:returns: 校验比特序列, shape (L,), 值为 0/1
"""
if _HAS_RUST_CRC:
return np.asarray(_rust_crc(np.asarray(data_bits, dtype=np.int64),
poly, crc_len, seed))
# 初始化移位寄存器
reg = seed & ((1 << crc_len) - 1)
for bit in data_bits:
# 取最高位
msb = (reg >> (crc_len - 1)) & 1
feedback = int(bit) ^ msb
reg = (reg << 1) & ((1 << crc_len) - 1)
if feedback:
reg ^= poly
# 将寄存器内容转成比特数组(高位在前)
parity = np.zeros(crc_len, dtype=int)
for i in range(crc_len):
parity[i] = (reg >> (crc_len - 1 - i)) & 1
return parity
[文档]
def crc_attach(data_bits: np.ndarray, poly: int, crc_len: int,
seed: int = 0, mask: np.ndarray | None = None) -> np.ndarray:
"""对输入信息比特序列附加CRC校验比特。
:returns: b_0, b_1, ..., b_{B-1}, 其中 B = A + L
"""
parity = crc_calculate(data_bits, poly, crc_len, seed)
if mask is not None:
parity = (parity + mask[:crc_len]) % 2
return np.concatenate([data_bits, parity])
[文档]
def crc_check(received_bits: np.ndarray, poly: int, crc_len: int,
seed: int = 0, mask: np.ndarray | None = None) -> bool:
"""对接收比特序列进行CRC校验。
:returns: True 表示校验通过(无错误),False 表示校验失败
"""
data_bits = received_bits[:-crc_len]
rx_parity = received_bits[-crc_len:].copy()
if mask is not None:
rx_parity = (rx_parity + mask[:crc_len]) % 2
calc_parity = crc_calculate(data_bits, poly, crc_len, seed)
return np.array_equal(rx_parity, calc_parity)