如何在 C# 中复制 Perl 的解包功能?
Posted
技术标签:
【中文标题】如何在 C# 中复制 Perl 的解包功能?【英文标题】:How can I replicate Perl's unpack functionality in C#? 【发布时间】:2008-10-08 11:28:20 【问题描述】:我正在尝试在 C# 中重新创建 Perl 脚本,但在创建目标系统所需的校验和值时遇到问题。
在 Perl 中,这个校验和是使用 unpack
函数计算的:
while (<PACKAGE>)
$checksum += unpack("%32C*", $_);
$checksum %= 32767;
close(PACKAGE);
其中PACKAGE
是.tar 文件输入流
我需要在 C# 中复制它,但找不到复制 unpack
函数的方法。
感谢所有帮助!
(我知道有更好的校验和计算可用,但无法更改目标系统,因此无法更改计算)
【问题讨论】:
【参考方案1】:Mono 中似乎有一个名为DataConvert 的库,它的编写目的是提供类似于Perl 的打包/解包的功能。这能满足您的需要吗?
【讨论】:
OP 用这个问题向互联网发送了垃圾邮件。显然他不是在寻找答案,因为我已经在 CodeProject 上向他提出了你的建议。 不幸的是,我无法在我们使用的服务器上安装 dataconvert 库,因此我正在寻找替代方案。我不会说在 7 个论坛上问这个问题是在向互联网发送垃圾邮件——我的假设是每个论坛会有不同的读者,我会从每个论坛得到不同的回复。..【参考方案2】:Perkl 的解包描述为 here 和 here。从此,您应该能够在 C# 中编写等价的代码。
【讨论】:
【参考方案3】:为了补充 Mitch Wheat 的评论,这里有一个 Java 实现(它只执行一个块)。我相信您会找到一种方法将其转换为 C#,并执行多个块。
int sum = 0;
for (byte b : buffer)
sum += (int) b & 255;
return sum % 32767;
希望这会有所帮助!
【讨论】:
【参考方案4】:在我在这里的测试中,使用 %32C 解包似乎是字节的加法总和,限制为 32 位。
print unpack("%32C*", 'A');
65
print unpack("%32C*", 'AA');
130
复制它应该不难。
【讨论】:
是的,我似乎遇到的问题是因为该文件是一个 tar,其中包含非标准的 ascii 字符,这些在 perl 脚本和我放在一起的 C# 脚本中会产生不同的结果。只是无法确定原因。 你在这两种情况下都确保二进制模式吗?无论文件格式是什么“tar”类型,以二进制(非翻译或非 ASCII)模式一次读取一个字节应该给出相同的字节,而不管语言如何。【参考方案5】:基于Chris Jester-Young和piCookie的cmets,我开发了如下函数。我希望你觉得它有用。
int fileCheckSum(const char *fileName)
FILE *fp;
long fileSize;
char *fileBuffer;
size_t result;
int sum = 0;
long index;
fp = fopen(fileName, "rb");
if (fp == NULL)
fputs ("File error",stderr);
exit (1);
fseek(fp, 0L, SEEK_END);
fileSize = ftell(fp);
fseek(fp, 0L, SEEK_SET);
fileBuffer = (char*) malloc (sizeof(char) * fileSize);
if (fileBuffer == NULL)
fputs ("Memory error",stderr);
exit (2);
result = fread(fileBuffer, 1, fileSize, fp);
if (result != fileSize)
fputs ("Reading error", stderr);
if (fileBuffer != NULL)
free(fileBuffer);
exit (3);
for (index = 0; index < fileSize; index++)
sum += fileBuffer[index] & 255;
fclose(fp);
if (fileBuffer != NULL)
free(fileBuffer);
return sum % 32767;
【讨论】:
以上是关于如何在 C# 中复制 Perl 的解包功能?的主要内容,如果未能解决你的问题,请参考以下文章
解包函数将如何在 perl 中用于此代码 $str =~ s/([^\w ])/'%'.unpack('H2', $1)/eg;