你好。也许有人知道一个真正的方法来获得同样的结果在 Delphi 和C#的下一行。
var
aStrStream: TStringStream;
aStr: string;
begin
aStr := 'Test';
aStrStream := TStringStream.Create('');
aStrStream.Write(aStr, SizeOf(Length(aStr)));
aStrStream.Position := 0;
aStr := DIMime.MimeEncodeStringNoCRLF(aStrStream.DataString);
aStrStream.Free;
//Got yJFVAA==
end;
以及
Encoding dest = Encoding.ASCII;
Encoding src = Encoding.Unicode;
byte[] srcBytes = src.GetBytes("Test");
byte[] destBytes = Encoding.Convert(src, dest, srcBytes);
Console.WriteLine(Convert.ToBase64String(destBytes));
//Got VGVzdA==
更新1:
谢谢你的详细回答。但情况是下一个。我有一个src代码的一些程序生成一个based64字符串的soksifikator。我尝试将它转换为C#。这个程序有很多行这样:
aLen := Length(aObj.RuleProxyName); //aObj.RuleProxyName - string
aStrStream.Write(aLen, SizeOf(aLen));
if aLen > 0 then
aStrStream.Write(aObj.RuleProxyName[1], aLen);
这就是为什么我不能使用aStrStream.WriteString
的原因。
1条答案
按热度按时间ej83mcc01#
更新
我之所以假设C#代码是目标代码,是因为 Delphi 代码显然是错误的。但是正如我所讨论的,C#代码也很奇怪。现在看来,原问题中的两个代码摘录都是假的。试图让C#与您发布的Delphi代码匹配是没有意义的,因为Delphi代码完全是错误的。
你真正需要做的是弄清楚真正的 Delphi 代码(而不是你的模拟代码)在做什么。
让我们来看看这个:
它将一个4字节的小端整数字符串长度写入一个流,然后在其后跟随ANSI编码的文本。 Delphi 代码使用了一个
TStringStream
,但这是对该类的滥用。该类用于存储文本,但很明显它包含了二进制和ANSI编码文本的混合。这段代码实际上应该使用内存流或类似的东西。在C#中,上面的摘录将翻译为:
下一个问题是
DIMime.MimeEncodeStringNoCRLF
做什么。我们无法知道,因为它不是一个标准类。正如我在最初的答案中所说的,你应该警惕任何试图对文本而不是二进制输入进行base64编码的代码。因此,为了取得进展,您需要尝试了解
DIMime.MimeEncodeStringNoCRLF
的实际功能。考虑到这似乎是一个Unicode之前的 Delphi ,它几乎肯定会将输入字符串视为字节数组并对其进行编码,在这种情况下,您可以使用Convert.ToBase64String(stream.ToArray())
来完成上面的摘录。原始答案
Delphi 代码有点混乱。例如,
SizeOf(Length(aStr))
没有任何意义。但无论如何,你都不应该使用Write
,而应该使用WriteString
。但即便如此,你还是把文本和二进制搞混了。你费了很大的劲把文本转换成ASCII,然后执行
aStrStream.DataString
,简单地把它转换回UTF-16。然后你把它馈送给MimeEncodeStringNoCRLF
。你还不如写:MimeEncodeStringNoCRLF('Test')
,我想它也会以同样的方式失败。我会重新开始,完全按照C#版本的方式编写代码。我会避免使用
TStringStream
,并利用 Delphi 的TEncoding
类在使用上尽可能接近.netEncoding
类的这一事实。因此,您确实可以对这段代码进行字面翻译。输出
如果您没有可用的
NetEncoding
单元(它是在XE 7中添加的),您可以使用手头上的任何其他base64编码器字节数组。我不得不说,我对您使用
DIMime.MimeEncodeStringNoCRLF
的做法相当怀疑,因为它会将文本转换为base64。这需要将文本隐式编码为二进制表示。而这种隐式编码至关重要,不应该以这种方式隐藏起来。这就是我说您混淆了文本和二进制的意思。请记住,base64将二进制编码为文本。并将文本解码为二进制。但MimeEncodeStringNoCRLF
将文本转换为文本,这意味着隐式文本编码。我个人的规则是,你永远不应该使用隐式文本编码进行这样的转换。如果你从文本开始,首先使用显式选择的编码转换为二进制,然后使用base64编码该二进制。
最后,我想知道为什么代码从文本转换为ASCII,然后转换为UTF-16。这似乎是一个相当奇怪的决定。C#代码真的在做你需要它做的事情吗?