news 2026/5/6 11:47:04

UVa 128 Software CRC

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 128 Software CRC

题目描述

你在一家大量使用个人电脑的公司工作。老板Penny Pincher\texttt{Penny Pincher}Penny Pincher博士一直想将这些电脑连接起来,但又不愿意花钱购买你建议的以太网卡。你无意中提到每台PC\texttt{PC}PC都自带一个异步串行口(无需额外费用),于是老板抓住机会,让你编写必要的软件来实现PC\texttt{PC}PC间的通信。

你了解到通信过程中容易出错,典型的解决方案是在每条消息末尾附加错误校验信息,以便接收程序能检测到传输错误(大多数情况下)。经过研究,你决定采用**CRC\texttt{CRC}CRC(循环冗余校验)**作为错误校验机制,并向老板提交了如下方案:

CRC\texttt{CRC}CRC生成机制

待传输的消息被视为一个很长的正二进制数。消息的第一个字节是该二进制数的最高有效字节,第二个字节是次高有效字节,依此类推。这个二进制数称为mmmmessage\texttt{message}message)。实际传输的不是mmm,而是一个新消息m2m_2m2,它由mmm和紧随其后的两字节CRC\texttt{CRC}CRC值组成。

CRC\texttt{CRC}CRC值的选取原则是:m2m_2m2除以某个161616位值ggg(生成器)的余数为000。这样接收程序只需将收到的消息除以ggg,若余数为000就认为没有发生传输错误。

你在书中发现大多数建议的ggg值都是奇数,但没有其他明显规律,因此你选择了g=34943g = 34943g=34943(十进制)作为生成器。

你的任务是设计一个算法,计算任意待发送消息对应的CRC\texttt{CRC}CRC值,并编写程序进行测试。

输入格式

每行输入包含不超过102410241024ASCII\texttt{ASCII}ASCII字符(每行字符不包括换行符)。
输入以第一列为#的行结束。

输出格式

对每个输入行,计算该行消息的CRC\texttt{CRC}CRC值,并以十六进制形式输出两个字节的CRC\texttt{CRC}CRC值(中间用空格分隔)。
注意每个CRC\texttt{CRC}CRC值应在000349423494234942(十进制)范围内。


题目分析与解题思路

本题的核心是计算给定消息的161616CRC\texttt{CRC}CRC校验码,使得附加CRC\texttt{CRC}CRC后的整个消息(视为一个大整数)能被g=34943g = 34943g=34943整除。

数学模型

设消息mmmkkk个字节组成:bk−1,bk−2,…,b0b_{k-1}, b_{k-2}, \dots, b_0bk1,bk2,,b0(其中bk−1b_{k-1}bk1是最高有效字节)。
mmm视为一个256256256进制的数,即:

m=bk−1⋅256k−1+bk−2⋅256k−2+⋯+b0⋅2560 m = b_{k-1} \cdot 256^{k-1} + b_{k-2} \cdot 256^{k-2} + \dots + b_0 \cdot 256^0m=bk1256k1+bk2256k2++b02560

附加两字节CRC\texttt{CRC}CRCccc0≤c<655360 \le c < 655360c<65536)后,得到新消息:

m2=m⋅65536+c m_2 = m \cdot 65536 + cm2=m65536+c

要求m2mod g=0m_2 \mod g = 0m2modg=0,即:

(m⋅65536+c)mod g=0 (m \cdot 65536 + c) \mod g = 0(m65536+c)modg=0

因此:

c=(g−(m⋅65536)mod g)mod g c = (g - (m \cdot 65536) \mod g) \mod gc=(g(m65536)modg)modg

注意ccc应输出为两个字节,即ccc000655356553565535之间,但题目保证g=34943g = 34943g=34943,所以c<gc < gc<g,自然满足。

算法设计

直接计算mmm可能非常大(最多102410241024字节,即281922^{8192}28192量级),必须边读边模ggg运算。

我们可以从最低有效字节开始计算mmod gm \mod gmmodg

设当前余数为rrr(初始为000),逐个处理字节bib_ibi(从最后一个字节开始向前):

r=(r+bi⋅256i)mod g r = (r + b_i \cdot 256^i) \mod gr=(r+bi256i)modg

256i256^i256i也会很大,需要预先计算256imod g256^i \mod g256imodg的模幂值。

可以预先计算了一个数组modular[i],其中:

modular[i] = (65536 * 256^i) mod g

注意这里65536 = 256^2,是因为在计算m⋅65536m \cdot 65536m65536时,相当于将mmm左移161616位(即乘以655366553665536)。代码中从最低字节开始累加时,直接使用了modular[j],其中jjj是当前字节的索引(从000开始)。

计算步骤

  1. 预处理modular[0..1024],其中modular[0] = 65536 mod gmodular[i] = (modular[i-1] * 256) mod g
  2. 对每个输入行(非空且不以#开头):
    • 从字符串末尾开始向前遍历(即从最低有效字节向最高有效字节)。
    • 对于位置jjj(从000开始)的字符line[i],累加(line[i] * modular[j]) mod g到余数residue
    • 遍历完成后,residue即为(m⋅65536)mod g(m \cdot 65536) \mod g(m65536)modg
    • 计算c = (g - residue) mod g
    • c转换为两个字节的十六进制输出。

边界情况

  • 空行:CRC\texttt{CRC}CRC值为00 00
  • 输入结束:第一列为#的行。

代码实现

// Software CRC// UVa ID: 128// Verdict: Accepted// Submission Date: 2015-12-01// UVa Run Time: 0.352s//// 版权所有(C)2015,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintMOD_BASE=34943;intmodular[1030];// 预处理 modular 数组:modular[i] = (65536 * 256^i) % MOD_BASEvoidgenerateModular(){modular[0]=65536%MOD_BASE;for(inti=1;i<=1024;i++)modular[i]=(modular[i-1]*256)%MOD_BASE;}// 将16位CRC值转换为两个字节的十六进制形式输出voidintToHex(intresidue){string hex="0123456789ABCDEF";cout<<hex[residue/256/16];cout<<hex[residue/256%16];cout<<" ";cout<<hex[(residue%256)/16];cout<<hex[residue%256%16];cout<<endl;}// 计算一行消息的CRC并输出voidsoftwareCRC(string line){intresidue=0;// 从最低有效字节开始累加for(inti=line.length()-1,j=0;i>=0;i--,j++)residue+=(line[i]*modular[j]%MOD_BASE);// 计算CRC值residue=(MOD_BASE-residue%MOD_BASE)%MOD_BASE;intToHex(residue);}intmain(intac,char*av[]){generateModular();string line;while(getline(cin,line)){if(line.length()==0){cout<<"00 00"<<endl;continue;}if(line[0]=='#')break;softwareCRC(line);}return0;}

样例说明

输入:

this is a test A #

输出:

77 FD 00 00 0C 86
  • 第一行消息"this is a test"CRC\texttt{CRC}CRC0x77FD
  • 第二行"A"的CRC为0x0C86
  • 空行输出00 00

总结

本题是一个典型的CRC\texttt{CRC}CRC校验码计算问题,关键在于理解消息被视为一个大整数,以及模运算在避免大数计算中的应用。通过预处理256imod g256^i \mod g256imodg的值,可以高效地逐字节计算余数,最终得到两字节的CRC\texttt{CRC}CRC校验码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 13:25:20

7-Zip压缩工具终极指南:开源压缩软件的深度解析与高效应用

7-Zip压缩工具终极指南&#xff1a;开源压缩软件的深度解析与高效应用 【免费下载链接】7-Zip 7-Zip source code repository 项目地址: https://gitcode.com/gh_mirrors/7z/7-Zip 在当今数字时代&#xff0c;文件压缩已成为日常工作和学习中不可或缺的技能。面对市面上…

作者头像 李华
网站建设 2026/5/1 16:26:42

区块链应用翻译:智能合约多语言支持方案

区块链应用翻译&#xff1a;智能合约多语言支持方案 &#x1f310; AI 智能中英翻译服务 (WebUI API) 项目背景与技术动因 随着全球区块链生态的快速发展&#xff0c;跨语言协作已成为去中心化应用&#xff08;DApp&#xff09;走向国际化的关键挑战。智能合约作为区块链世界中…

作者头像 李华
网站建设 2026/5/4 23:54:28

日志分析助力OCR调试:定位图像预处理瓶颈

日志分析助力OCR调试&#xff1a;定位图像预处理瓶颈 &#x1f4d6; 项目简介 在现代文档数字化、自动化信息提取等场景中&#xff0c;OCR&#xff08;光学字符识别&#xff09;技术已成为不可或缺的一环。它能够将图像中的文字内容自动转换为可编辑的文本格式&#xff0c;广泛…

作者头像 李华
网站建设 2026/5/5 10:40:47

海尔Haier智能家居集成完整指南:5分钟快速上手终极教程

海尔Haier智能家居集成完整指南&#xff1a;5分钟快速上手终极教程 【免费下载链接】haier 项目地址: https://gitcode.com/gh_mirrors/ha/haier 海尔Haier智能家居集成是HomeAssistant中最强大的海尔设备连接解决方案&#xff0c;能够将您所有的海尔智家设备无缝接入智…

作者头像 李华
网站建设 2026/4/30 9:18:13

优质期刊分享!工程技术-机械 学科领域!

期刊名称&#xff1a;MachinesJCR&#xff1a; Q2中科院&#xff1a; 3区影响因子&#xff1a;2.1ISSN&#xff1a;2075-1702期刊类型&#xff1a;SCI/SSCI/AHCI收录数据库&#xff1a;SCI(SCIE),Scopus学科领域&#xff1a;工程技术-机械期刊简介期刊定位Machines 是一本国际同…

作者头像 李华