我在Internet上获得此Luhn
函数,当我为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;
答案 0 :(得分:6)
Migrating Delphi Code to Mobile from Desktop | Use 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}
使用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;
使用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;
答案 1 :(得分:5)
问题是,默认情况下,字符串为零,基于移动编译器,但默认情况下基于桌面编译器。您需要调整代码以解决此问题。变化
Code[i]
到
Code[i-1]
我建议使用
{$ZEROBASEDSTRINGS ON}
如果您希望在移动和桌面目标之间共享代码。详情请见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;
请注意,我故意避免使用索引。这样做可以让我们完全支持零基或一基指数的问题。