Delphi 10:关于将 String[25] 的某些 char 值更改为“?”,我该怎么办?

Delphi 10: What can I do about String[25] changing some char values to "?"

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

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

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

但如果值为字符串[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'

我在记录中使用字符串[],当writing/reading数据to/from磁盘

我该如何解决这个问题?

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

/弗莱明

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

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

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

中的默认字符串类型

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


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

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

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

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