65.9K
CodeProject 正在变化。 阅读更多。
Home

用于编码和解码 yEnc 数据的 C# 组件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (15投票s)

2004年3月28日

CPOL

4分钟阅读

viewsIcon

108783

downloadIcon

3056

一个经过全面测试的组件,能够编码和解码 yEnc 数据。

Sample Image - yenc.gif

引言

这是 yEnc 算法的一种实现,如 http://www.yenc.org/ 所述。yEnc 不是官方标准,但它无疑是二进制新闻组中一种非常流行的编码方法。就算法而言,yEnc 非常简单。它使用 8 位字符来编码二进制数据。由于二进制数据通常存储为 8 位字节,因此它不需要做太多事情 :)

yEnc 之所以受欢迎,是因为它使用一个完整的字节来编码数据,而其他方法仅使用 7 位。根据该网站的说法,这意味着使用 yEnc 编码的消息会减小 33-40%。更小意味着上传和下载更快,这在处理大型二进制文件时非常重要。它还有其他好处,即可选的 CRC32 校验。

我的实现从两个角度来看都很有趣

  1. 这是唯一用 C# 编写的开源实现
  2. 它被实现为一个加密转换 - 稍后将详细介绍

关于 yEnc 的一些信息

新闻组消息有一些特殊性

  • 消息必须分成行,每行最多约 1000 个字符
  • 某些字符具有特殊含义,因此需要对其进行转义

当前的 yEnc 算法默认转义 CR、LF 和 NULL 字符。但是,各个编码器可以自由选择转义其他字符。按照惯例,行会在 128 个字符或 256 个字符处断开。也支持其他行长度。

yEnc 数据以行开头的 =ybegin 标签开始。该标签具有附加属性,用于指定预期的字节数、文件名以及行长度。支持多部分消息。数据以以 =yend 开头的行结束。之所以使用“=y”,是因为算法的性质,它永远不会自然出现在数据中。

使用代码

我对该算法的实现仅处理数据的编码和解码,而不处理消息的解析,甚至不处理 yEnc 头部和尾部的解析。对我来说,这是一个独立的挑战,我将留给其他人来解决。

最初,我将编码器编写为 `System.Text.Encoder` 的实现。然而,我很快意识到,尽管我可以将数据读取为文本,但实际上我处理的是字节。也许从一开始我就应该明白这一点,但有时需要一些时间 :( 最终,我决定最好将其实现为 `ICryptoTransform`。这并非暗示它是一种加密算法,只是它以类似的方式转换数据 - 输入数据的长度不一定等于输出数据的长度。微软选择以类似的方式实现 Base64 转换对象。

这样做的好处是,您可以将这些对象与 `CryptoStream` 对象一起使用,这是一个相当容易使用的接口,并且自动添加了对流的支持。我再次强调,**这不是一种加密技术** - 我只是利用现有的框架对象和接口来增强我的对象的强大功能。

要编码一些 yEnc 数据,您的代码可能如下所示

MemoryStream ms = new MemoryStream();  
//this could be any stream we want to write to YEncEncoder encoder = new YEncEncoder(); CryptoStream cs = new CryptoStream(ms, encoder, CryptoStreamMode.Write); StreamWriter w = new StreamWriter(cs); w.Write("Test string"); //make sure everything is written out w.Flush(); cs.Flush();

要再次解码它,代码可能如下继续

//reading back from the memorystream
ms.Position = 0;        
YEncDecoder decoder = new YEncDecoder();
CryptoStream cs2 = new CryptoStream(ms, decoder, CryptoStreamMode.Read);
StreamReader r = new StreamReader(cs2);
string finalText = r.ReadToEnd();
        

如果您要加密数据,这通常是您会编写的标准代码,唯一的区别是我们使用的是 `yEncEncoder` 和 `yEncDecoder`,而不是系统提供的加密算法。

关注点

我使用了 Phil Bolduc 的 CRC32 算法实现,该实现在 https://codeproject.org.cn/csharp/crc32_dotnet.asp。不幸的是,其中存在一些错误,消耗了我大量的时间。我不得不进行一些修改才能使其 100% 工作。除此之外,代码是我自己的原创作品,不基于任何其他实现。您可以随意用于任何目的,只要在代码注释中注明即可。

可下载的代码包含大量 NUnit 测试,这些测试已对代码进行了充分的测试,我对此表示满意。它们应该使任何想要添加功能的人都能轻松地扩展代码。

© . All rights reserved.