【问题标题】:Delphi 10: What can I do about String[25] changing some char values to "?"Delphi 10:String[25] 将一些 char 值更改为“?”我该怎么办?
【发布时间】:2021-05-05 22:44:17
【问题描述】:

我已将 Delphi 7.1 应用程序移植到 Delphi 10.3。 我有一些简单的加密/解密功能。 如果我加密字符串值并加密它们,一切都很好:

var
   test, encrypted, decrypted : string;
begin
  test := 'XXXXXXXX'; // hidden message 
  encrypted := _common.encrypt(test);
  decrypted := _common.decrypt(encrypted );  
end;

在这种情况下,一切都按预期工作,即使使用特殊字符,加密后将是:'y'#$0080'vn'

但如果值是string[25],它对特殊字符的处理方式不同:

var
   test,decrypted : string;
   encrypted : string[25]
begin
  test := 'XXXXXXXX'; // hidden message 
  encrypted := _common.encrypt(test);
  decrypted := _common.decrypt(encrypted);  
end;

在这种情况下,除非加密字符串包含此示例中的特殊字符,否则一切都会按预期运行 res1 将是:'y?vn'

在向磁盘写入/读取数据时,我在记录中使用 string[]

我该如何解决这个问题?

我可以为记录类型使用不同的字符串类型吗?

/弗莱明

【问题讨论】:

  • 加密时应该返回字节,而不是字符串。
  • string[25]ShortString,但 stringUnicodeString,因此您正在调用可能丢失非 ASCII 字符 > $7F 的 Unicode->ANSI 转换,这正是你所看到的正在发生。
  • Delphi and Unicode - 你需要知道的一切。
  • 我的问题是我已经用旧的加密存储了我必须读取的数据,所以我必须使用一个字符串数组,但是一个普通的字符串而不是一个短字符串。还有其他方法可以为 255 字节字符设置固定大小的字符串数组吗?

标签: delphi encryption delphi-7 delphi-xe


【解决方案1】:

自 Delphi 7 以来,string 类型已从一字节 ANSI 字符更改为两字节 Unicode 字符。但是,固定长度的string[n] 仍然是一个单字节的ANSI 字符串。因此,您正在混合不同的字符串类型。最简单的解决方法可能是将那些声明为string 的变量改为声明为AnsiString

【讨论】:

  • 我明白,但我需要支持遗留数据,那么如何修复这个字符串 [xx] 是一个我丢失非 ASCII 字符的短字符串 > $7F,我可以使用什么作为固定字符串array 而不是 string[25] ...因为我需要能够读取旧的格式化数据。
  • 如果你真的有两个字节的字符,你应该使用一个没有固定长度的字符串,或者你可以使用一个 char 数组 [0..24],因为现在 char 是两个字节的。跨度>
  • 如何将字符串保存到 char 数组[0..24]?
  • StrpLCopy(destarray,sourcestring,25);
  • 使用StrpLCopy会产生这个编译器错误:[dcc32 Error] mzm_common.pas(1759): E2010 Incompatible types: 'array[0..24] of Char' and 'PWideChar'
【解决方案2】:

您在两个代码示例中没有得到相同结果的原因是第一个代码示例完全依赖于使用默认字符串类型,在 Delphi 10.3 中是 WideString(每个字符两个字节)。

但在您的第二个代码示例中,您将结果声明为string[25],这是一个短字符串类型。现在不像普通的字符串类型 ShortString 类型只能包含单字节字符或者换句话说只支持 AnsiString 类型,这是 Delphi 7 中的默认字符串类型。

所以当你混合两种不同的字符串类型时,你不会得到相同的结果。


处理加密和解密时的一般规则是根本不使用字符串,而是使用原始二进制数据。为什么?

在 Delphi 7 的时候,字符串已经受到当前使用的字符串编码的影响。因此,如果您在使用一种字符串编码的计算机上加密了某个字符串,并在使用另一种字符串编码的计算机上解密,您会得到错误的结果。

现在在使用 WideString 和 Unicode 编码的现代 Delphi 版本上,这不再造成这样的问题,但还有另一个潜在问题,因为在 Windows 上,字符串是基于 1 的(字符串中第一个字符的索引是 1),而在移动平台上,字符串是 0基于(第一个字符的索引为 0)。

因此,我强烈建议您重新设计加密/解密例程以处理原始二进制数据。

【讨论】:

  • "默认字符串类型,在 Delphi 10.3 中为 WideString" - 自 Delphi 2009 起,默认字符串类型为 UnicodeString,而不是 WideString。它们都是 UTF-16 编码的字符串,但是它们有非常不同的管理要求(UnicodeString 是引用计数并使用 Delphi 内存管理器分配的,而 WideString 不是引用计数的,而是使用 COM 内存管理器分配的) .
  • 从 10.4 开始,在桌面和移动编译器中,字符串的默认索引从 1 开始。来自docwiki.embarcadero.com/RADStudio/Sydney/en/…注意:在 Delphi 10.4 之前,移动编译器默认使用基于 0 的字符串索引。
猜你喜欢
  • 2015-02-08
  • 1970-01-01
  • 2013-12-04
  • 2012-04-12
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
相关资源
最近更新 更多