我从这个答案中获取了一个Python片段(稍加修改)来计算以太网crc32帧检查序列:
msg = '00'
data = bytes.fromhex(msg)
print(data)
print(msg)
crc = zlib.crc32(data)&0xFFFFFFFF
for i in range(4):
b = (crc >> (8*i)) & 0xFF
print('{:02X}'.format(b))
Run Code Online (Sandbox Code Playgroud)
00对于它输出的消息,这是此答案8D EF 02 D2的位反转解决方案。到目前为止,一切都很好。
现在这里说,
对包括 CRC 码的接收帧数据运行 CRC 算法将始终导致无错误接收数据的零值,因为 CRC 是数据除以多项式的余数。然而,这种技术可能无法检测错误,其中带有尾随零的数据也将导致相同的零余数。为了避免这种情况,发送方在将 FCS 附加到有效负载数据的末尾之前对其进行补充(每个位都取反)。这样,当数据正确接收时,算法结果将始终是 0xC704DD7B 的 CRC32 残差。
但如果我输入00 8D EF 02 D2计算器,结果是1C DF 44 21,而不是所说的余数。我还尝试了其他组合,因为通常必须反转字节中的位或其他什么(我实际上对所有这些反转的东西感到困惑,但我希望,尝试几种可能性后的良好结果将引导我走向正确的反转),但没有任何成功:
00 D8 FE 20 2D -> 66 40 C3 4A
00 D2 02 EF 8D -> DF 42 14 …Run Code Online (Sandbox Code Playgroud) 我想验证我的 ZIP 文件是否具有正确的 CRC-32 校验和。
\n我读到,在 ZIP 文件中,CRC-32 数据位于字节 14 到 17 中:
Offset Bytes Description[30]\n0 4 Local file header signature = 0x04034b50 (read as a little-endian number)\n4 2 Version needed to extract (minimum)\n6 2 General purpose bit flag\n8 2 Compression method\n10 2 File last modification time\n12 2 File last modification date\n14 4 CRC-32 of uncompressed data\n18 4 Compressed size\n22 4 Uncompressed size\n26 2 File name length (n)\n28 2 Extra field length (m)\n30 n File name\n30+n m Extra field …Run Code Online (Sandbox Code Playgroud) 我有一个名为 hello.txt 的文件,其中包含以下内容:
hello
Run Code Online (Sandbox Code Playgroud)
当我在该文件上执行 linux crc32 时,如下所示:(我通过 sudo apt install libarchive-zip-perl 安装)
crc32 hello.txt
Run Code Online (Sandbox Code Playgroud)
我得到:
363a3020
Run Code Online (Sandbox Code Playgroud)
当我想使用一些在线计算器或 npm 库(来自 node.js 的 crc)时,我仅在文本上执行并得到以下结果:
3610a686
Run Code Online (Sandbox Code Playgroud)
这是不同的。我怎样才能检查这个结果是否相同?这里有什么区别?有人可以解释一下吗?
我通过串行端口发送和接收原始二进制数据,因此我在向量中存储了预定义的消息u8。我需要计算 16 位 CRC 并在发送之前将其附加到末尾,但是我不断遇到转换和整数溢出问题。这是我之前在 C 中完成计算的方式:
void Serial::AddCRC(void *data, int len, void *checksum)
{
uint8_t *dataPtr = (uint8_t *)data;
uint8_t *crcPtr = (uint8_t *)checksum;
uint16_t crc = 0x0;
unsigned char x;
int byteCount = 0;
while ((len--) > 0) {
x = (unsigned char)(crc >> 8 ^ dataPtr[byteCount++]);
x ^= (unsigned char)(x >> 4);
crc = (uint16_t)((crc << 8) ^ (x << 12) ^ (x << 5) ^ x);
}
crcPtr[0] = crc >> 8;
crcPtr[1] = …Run Code Online (Sandbox Code Playgroud) 情况是这样的:我的系统(Win XP Pro)无法从DVD磁盘复制一个巨大的视频文件(大约6演出),这可能是有缺陷的,有划痕的或者其他什么但可以使用带有几帧的mplayer播放虽然充满马赛克.当复制过程持续一段时间后,系统将中止工作并向我发出警告"发生循环冗余校验校验和错误".然后复制的所有内容都会自动删除.
我在想Perl应用可能会解决这个问题.我的想法是:我一次复制一兆的视频数据.如果发生读取错误,我让perl忽略这个特定的1兆的数据,并且一次复制其余的视频仍然是一个兆字节.
顺便说一句,我也注意到一些商业软件可以完成这项工作,但试验中存在局限性.
以下脚本是我到目前为止尝试过的.它一次从有缺陷的DVD磁盘复制数据一兆,但它像Win XP一样失败.唯一的区别是perl不会删除已经复制的内容.就我而言,它将大约900兆的视频数据复制到我的硬盘上,这个900兆的部分视频仍然可以用mplayer播放.但我的目标是复制所有好的,大多数,只留下所有坏的,少数.
use strict;
use warnings;
$/ = \1_048_576;
open my $in, "<", 'D:\tobecopied.mkv' or die $!;
binmode $in;
open my $out, ">", 'E:\copied.mkv' or die $!;
binmode $out;
while (<$in>) {
print $out $_;
}
Run Code Online (Sandbox Code Playgroud)
问题是我不知道如何实现这一目标.希望有人在这里可以给我一个提示或线索.总是如此谢谢:)
有人可以用C#编码CRC64反向算法吗?我无法编码,无法理解任何事情.谢谢,
我从C++复制了CRC64校验和代码并将其转换为C#.NET.整个代码显示如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CRC64
{
public class cCRC64
{
public UInt64[] crc64_table = {
0x0000000000000000, 0x42F0E1EBA9EA3693,
0x85E1C3D753D46D26, 0xC711223CFA3E5BB5,
0x493366450E42ECDF, 0x0BC387AEA7A8DA4C,
0xCCD2A5925D9681F9, 0x8E224479F47CB76A,
0x9266CC8A1C85D9BE, 0xD0962D61B56FEF2D,
0x17870F5D4F51B498, 0x5577EEB6E6BB820B,
0xDB55AACF12C73561, 0x99A54B24BB2D03F2,
0x5EB4691841135847, 0x1C4488F3E8F96ED4,
0x663D78FF90E185EF, 0x24CD9914390BB37C,
0xE3DCBB28C335E8C9, 0xA12C5AC36ADFDE5A,
0x2F0E1EBA9EA36930, 0x6DFEFF5137495FA3,
0xAAEFDD6DCD770416, 0xE81F3C86649D3285,
0xF45BB4758C645C51, 0xB6AB559E258E6AC2,
0x71BA77A2DFB03177, 0x334A9649765A07E4,
0xBD68D2308226B08E, 0xFF9833DB2BCC861D,
0x388911E7D1F2DDA8, 0x7A79F00C7818EB3B,
0xCC7AF1FF21C30BDE, 0x8E8A101488293D4D,
0x499B3228721766F8, 0x0B6BD3C3DBFD506B,
0x854997BA2F81E701, 0xC7B97651866BD192,
0x00A8546D7C558A27, 0x4258B586D5BFBCB4,
0x5E1C3D753D46D260, 0x1CECDC9E94ACE4F3,
0xDBFDFEA26E92BF46, 0x990D1F49C77889D5,
0x172F5B3033043EBF, 0x55DFBADB9AEE082C,
0x92CE98E760D05399, 0xD03E790CC93A650A,
0xAA478900B1228E31, 0xE8B768EB18C8B8A2,
0x2FA64AD7E2F6E317, 0x6D56AB3C4B1CD584,
0xE374EF45BF6062EE, 0xA1840EAE168A547D,
0x66952C92ECB40FC8, 0x2465CD79455E395B,
0x3821458AADA7578F, 0x7AD1A461044D611C, …Run Code Online (Sandbox Code Playgroud) 我第一次使用CRC(boost::crc_32_type),我注意到process_bytes()使用相同的参数调用方法两次我得到不同的结果.这是正常的吗?
#include <boost/crc.hpp>
#include <ios> // for std::ios_base, etc.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string data1, data2;
boost::crc_32_type result1, result2;
data1 = "This is a test string";
data2 = data1;
result1.process_bytes(data1.c_str(), data1.length());
cout << "result1: " << hex << uppercase << result1.checksum() << endl;
result1.process_bytes(data1.c_str(), data1.length());
cout << "result1: " << hex << uppercase << result1.checksum() << endl;
result2.process_bytes(data1.c_str(), data1.length());
cout << "result2: " << hex << uppercase << result2.checksum() << …Run Code Online (Sandbox Code Playgroud) 遗憾的是,计算大型CRC32的正确方法是什么还不足以让我理解如何在大小为1kb <= x <= 128kb的文件上实现crc的计算.mhash库隐藏了这个问题,因此对我来说是合适和方便的,但是,我想请你解释一下如何将多个crcs合二为一.
也许这是一个错误的问题(这将是我无知的衡量标准),但具体而言,如何将前一次迭代中计算出的crc添加到下一个要处理的块中是合法的?这是否会严重降低整体计算速度,是否可能会将新异常引入其他未被清除的数据?TIA
所以我有这个C代码,我需要移植到C#:
C代码:
uint16 crc16_calc(volatile uint8* bytes, uint32 length)
{
uint32 i;
uint32 j;
uint16 crc = 0xFFFF;
uint16 word;
for (i=0; i < length/2 ; i++)
{
word = ((uint16*)bytes)[i];
// upper byte
j = (uint8)((word ^ crc) >> 8);
crc = (crc << 8) ^ crc16_table[j];
// lower byte
j = (uint8)((word ^ (crc >> 8)) & 0x00FF);
crc = (crc << 8) ^ crc16_table[j];
}
return crc;
}
Run Code Online (Sandbox Code Playgroud)
移植C#代码:
public ushort CalculateChecksum(byte[] bytes)
{
uint j = 0; …Run Code Online (Sandbox Code Playgroud) 我有这个C代码块,我不能为我的生活理解.我需要为我发送给该方法的某个字节数组计算CRC-16,它应该给出msb(最高有效字节)和lsb(最低有效字节).我还获得了一个C编写的应用程序来测试一些功能,该应用程序还为我提供了发送内容和通过COM端口接收的内容的日志.
有点奇怪的是,我输入了我在日志中找到的这个在线计算器的十六进制字符串,但它给了我不同的结果.
我把这个方法翻译成C#,但我不明白某些方面:
这是代码块:
unsigned short CalculateCRC(unsigned char* a_szBufuer, short a_sBufferLen)
{
unsigned short usCRC = 0;
for (short j = 0; j < a_sBufferLen; j++)
{
unsigned char* pucPtr = (unsigned char*)&usCRC;
*(pucPtr + 1) = *(pucPtr + 1) ^ *a_szBufuer++;
for (short i = 0; i <= 7; i++)
{
if (usCRC & ((short)0x8000))
{
usCRC = usCRC << 1;
usCRC = usCRC ^ ((ushort)0x8005);
}
else
usCRC = …Run Code Online (Sandbox Code Playgroud)