Delphi ORD函数未返回期望值

我有2个函数,其中一个使用Ord()函数加密,另一个用于解密字符串。除扩展的Ascii代码外,它都很好用。

如果我使用字母ê(Ascii代码136),则Ord()函数将返回234,正如我期望的那样,它将返回136。

如果我对加密的字符串进行解密,则得到的结果与原始字符串的结果将有所不同,ê变成j。

有人可以帮忙解决这个问题吗?

procedure TForm1.btnEncryptClick(Sender: TObject);
var
  sTempString : string;
  iIndex,i: integer;
begin
  sTempString  := edtOriginalString.Text ;
  for iIndex := 1 to length(sTempString) do
  begin
    i := ord(sTempString[iIndex]);
    i := i shl 1;
    sTempString[iIndex] := Char(i);
  end;
  edtEncryptedString.Text := sTempString;
end;

procedure TForm1.btnDecryptClick(Sender: TObject);
var
  sTempString : string;
  iIndex,i : integer;
begin
  sTempString  := edtEncryptedString.Text ;
  for iIndex := 1 to length(sTempString) do
  begin
    i := ord(sTempString[iIndex]);
    i := i shr 1;
    sTempString[iIndex] := char(i);
  end;
  edtDecryptedString.Text := sTempString;
end;

Delphi ORD函数未返回期望值

lixiaoxuaner 回答:Delphi ORD函数未返回期望值

  

如果我使用字母ê(Ascii代码136)

不,这实际上是错误的。 ASCII仅包含128个字符(0到127)。

但是,ê是Unicode字符U + 00EA:带圆圈符号的拉丁文小写字母E。

EA(十六进制)的确是234(十进制)。


Delphi字符和字符串在Delphi 2009之前为8位,在Delphi 2009及更高版本中为Unicode。

因此,在您的情况下,Delphi 6是一个8位字符。

因此,您的左移将使您失去最高有效位(MSB),并且您不可能希望将其恢复。

实际上,如果我们考虑ê(234),我们有

1110 1010 (ê)

将位向左移动一步,我们得到

1101 0100

将位向右移动一步,我们得到

0110 1010 (j).

因此,我们丢失了信息。


但是,您的方法用于ASCII字符(不适用于127以上的任何字符,因为它们都具有一个MSB(因此,即使Ord确实返回了136,也不会起作用)。>


因此,如果要支持127以上的字符,则需要放弃或重新设计“加密”方法。例如,可以旋转位而不是移动它们。也可以将它们反转(使用not)。

如果您选择旋转而不是平移,则会得到以下提示:

1110 1010 (ê)
rotate left:
1101 0101
rotate back (right):
1110 1010 (ê)

尽管这与您的实际问题无关,但是您可能仍然想知道为什么Ord并没有返回您期望的136。

好吧,在Unicode之前(主要是在1990年代和更早的年代),仅存在许多不同的(不兼容)字符编码。通常,一个8位编码/代码页(字符0..255)包含ASCII字符(0..127),然后为其余字符(128..255)做出自己的选择。由于ê不是ASCII字符,这意味着这些“扩展ASCII”代码页中只有一部分可能包含ê,而在包含ê的那些代码页中,实际数字值可能会大不相同。

换句话说,您的消息来源声称ê为136,而您的Delphi程序使用的是不同的8位代码页。

在Unicode的现代世界中,这种问题不再存在。

本文链接:https://www.f2er.com/3103890.html

大家都在问