我Luhn在Internet上获得此功能,当我为Windows32 VCL编译它时它是正确的.但是当我编译它以在Android应用程序中使用时,我得到了一个False而不是True我怀疑它是因为它正在转换为utf8期望ascii被转换的字节.
那么我该怎么做才能在Android上正常工作呢?
function Luhn(Code: string): Boolean;
var
i, sum: integer;
temp: byte;
begin
{ calcula o algorítimo luhn, usado no iccid }
sum := 0;
for i:= length(Code) downto 1 do
begin // Run the characters backwards
temp := byte(Code[i])-48; // Convert from ASCII to byte
if (length(Code)-i) mod 2 = 0
then sum := sum + temp // Odd characters just add
else if temp < 5
then sum := sum + 2*temp // Even characters add double
else sum := sum + (2*temp)-9; // or sum the digits of the doubling
end;
Result := sum mod 10 = 0; // Return true if sum ends in a 0
if Result then
Toast(Code+#13+'True')
else
Toast(Code+#13+'False');
end;
Run Code Online (Sandbox Code Playgroud)
像David所说,这个问题与桌面和移动编译器默认情况下不同地索引字符串有关.字符串在桌面编译器中仍然是1索引的,但在移动编译器中默认为0索引.这在文档中描述:
从桌面迁移Delphi代码到移动设备| 使用0-Based Strings
要使代码以您不必处理ZBS差异的方式工作,您可以:
用于{$ZEROBASEDSTRINGS OFF}在移动设备上返回基于1的索引
{$IFDEF NEXTGEN}
{$ZEROBASEDSTRINGS OFF}
{$ENDIF}
function Luhn(Code: string): Boolean;
var
i, sum: integer;
temp: byte;
begin
{ calcula o algorítimo luhn, usado no iccid }
sum := 0;
for i := Length(Code) downto 1 do begin // Run the characters backwards
temp := byte(Ord(Code[i]))-48; // Convert from ASCII to byte
if (Length(Code)-i) mod 2 = 0 then
sum := sum + temp // Odd characters just add
else if temp < 5 then
sum := sum + (2*temp) // Even characters add double
else
sum := sum + (2*temp) - 9; // or sum the digits of the doubling
end;
Result := sum mod 10 = 0; // Return true if sum ends in a 0
if Result then
Toast(Code+#13+'True')
else
Toast(Code+#13+'False');
end;
{$IFDEF NEXTGEN}
{$ZEROBASEDSTRINGS ON}
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)使用Low(String)和High(String)系统功能:
function Luhn(Code: string): Boolean;
var
i, sum: integer;
temp: byte;
begin
{ calcula o algorítimo luhn, usado no iccid }
sum := 0;
for i := High(Code) downto Low(Code) do begin // Run the characters backwards
temp := byte(Ord(Code[i]))-48; // Convert from ASCII to byte
if (High(Code)-i) mod 2 = 0 then
sum := sum + temp // Odd characters just add
else if temp < 5 then
sum := sum + (2*temp) // Even characters add double
else
sum := sum + (2*temp) - 9; // or sum the digits of the doubling
end;
Result := sum mod 10 = 0; // Return true if sum ends in a 0
if Result then
Toast(Code+#13+'True')
else
Toast(Code+#13+'False');
end;
Run Code Online (Sandbox Code Playgroud)使用TStringHelper助手类:
uses
..., SysUtils;
function Luhn(Code: string): Boolean;
var
i, sum: integer;
temp: byte;
begin
{ calcula o algorítimo luhn, usado no iccid }
sum := 0;
for i := Code.Length-1 downto 0 do begin // Run the characters backwards
temp := byte(Ord(Code.Chars[i]))-48; // Convert from ASCII to byte
if (Code.Length-1-i) mod 2 = 0 then
sum := sum + temp // Odd characters just add
else if temp < 5 then
sum := sum + (2*temp) // Even characters add double
else
sum := sum + (2*temp) - 9; // or sum the digits of the doubling
end;
Result := sum mod 10 = 0; // Return true if sum ends in a 0
if Result then
Toast(Code+#13+'True')
else
Toast(Code+#13+'False');
end;
Run Code Online (Sandbox Code Playgroud)问题是,默认情况下,字符串为零,基于移动编译器,但默认情况下基于桌面编译器.您需要调整代码以解决此问题.更改
Code[i]
Run Code Online (Sandbox Code Playgroud)
至
Code[i-1]
Run Code Online (Sandbox Code Playgroud)
我推荐使用
{$ZEROBASEDSTRINGS ON}
Run Code Online (Sandbox Code Playgroud)
如果您希望在移动和桌面目标之间共享代码.详情请访问:http://docwiki.embarcadero.com/RADStudio/en/Zero-based_strings_(Delphi)
一些旁白:
ord()从字符中获取序数值.odd()函数而不是显式mod测试.所以,我个人会写这样的代码:
function LuhnChecksumValid(const Value: string): Boolean;
var
C: Char;
Digit: Integer;
Sum: Integer;
OddChar: Boolean;
begin
if Value.Length=0 then
Exit(False);
Sum := 0;
OddChar := odd(Value.Length);
for C in Value do
begin
Digit := ord(C) - ord('0');
if not InRange(Digit, 0, 9) then
Exit(False);
if OddChar then
inc(Sum, Digit)
else if Digit < 5 then
inc(Sum, 2*Digit)
else
inc(Sum, 2*Digit - 9);
OddChar := not OddChar;
end;
Exit((9*Sum) mod 10 = 0);
end;
Run Code Online (Sandbox Code Playgroud)
请注意,我故意避免使用索引.这样做可以让我们完全支持零基或一基指数的问题.