将Delphi转换为Java(我的代码是正确的吗?)

时间:2016-10-28 18:42:03

标签: java delphi

我有这个Delphi代码

const
  C1 = 52845;
  C2 = 22719;

Function Encrypt(const S: String; Key: Word): String; cdecl ;
var
  I: byte;
  J : Integer;
  Str : String ;
begin
      Str := S ;
      for I := 1 to Length(S) do begin
        J:=byte(S[I]) xor (Key shr 8);
        Str[I] := Char(J);
        Key := (byte(Str[I]) + Key) * C1 + C2;
      end;
      Result:= '';
      for I := 1 to Length(S) do begin
        Result:= Result + StringOfChar('0' , 3 - Length(IntToStr(byte(Str[I]))) ) + IntToStr(byte(Str[I]));
      end;
end;

我想将此代码转换为java

我写这个

 public static String EncryptePassword(String S,int Key){
        int C1 = 52845;
        int C2 = 22719;

        String Str=S;
        String Result="";
        int J;
        for(int i=0;i<S.length();i++){

            J = (byte) S.charAt(i) ^ (byte) (Key>> 8);
            Str+= (char) J;
            Key=((byte) Str.charAt(i)+Key)*C1+C2;
        }
        for(int i=0;i<S.length();i++){
            Result+=repeat("0",3-String.valueOf( Integer.valueOf((byte) Str.charAt(i))).length())+ (byte) Str.charAt(i);

        }
        return Result;
    }

这个java代码等于Delphi代码吗?

1 个答案:

答案 0 :(得分:5)

代码不相同。特别是Delphi中的这一行:

Str[I] := Char(J);

正在替换字符串中的字符,而Java中的这一行:

Str += (char) J;

将字符附加到字符串的末尾。

所以Str会有两种不同的结果。

在Java中,字符串是不可变的,您无法修改字符。但是,您可以使用旧字符串中的片段构造一个新字符串,然后使用新字符串替换旧字符串。或者更好的是,您可以使用StringBuilder。

Java的翻译可能看起来更像这样:

private static int C1 = 52845;
private static int C2 = 22719;

private static int toUnsignedByte(char c)
{
    // in Delphi, Byte is an 8-bit unsigned type, but Java does not have
    // an equivalent type. Casting a Char to a Byte truncates the value
    // to 8 bits. Use a signed integer and limit its value to the
    // same range as a Byte...
    //
    return ((int) c) & 0xFF;
}

public static String EncryptePassword(String S, int Key)
{
    // in Delphi, Word is a 16-bit unsigned type, but Java does not have
    // an equivalent type. Use a signed integer and limit its value
    // to the same range as a Word...
    //
    if ((Key < 0) or (Key > 0xFFFF))
        throw new IllegalArgumentException("Key is outside the valid range of values");

    int J;
    StringBuilder Str = new StringBuilder(S);

    for(int I = 0; I < S.length(); ++I)
    {
        J = toUnsignedByte(S.charAt(I)) ^ (Key >> 8);
        Str.setCharAt(I, (char) J);
        Key = ((toUnsignedByte(Str.charAt(I)) + Key) * C1 + C2) & 0xFFFF;
    }

    StringBuilder Result = new StringBuilder(S.length() * 3);

    for(int I = 0; I < S.length(); ++I)
    {
        Result.append(String.format(Locale.US, "%03d", toUnsignedByte(Str.charAt(I))));
    }

    return Result.toString();
}

然而,需要注意的是,在Delphi 2007及更早版本中,String是一个8位的Ansi字符串,但在Delphi 2009及更高版本中,它是一个16位的Unicode字符串。 Java字符串是16位Unicode。你没有说你试图从哪个版本的Delphi移植代码,但如果它是一个Ansi版本,那么翻译可能看起来更像是这样:

private static int C1 = 52845;
private static int C2 = 22719;

private static int toUnsignedByte(byte b)
{
    // in Delphi, Byte is an 8-bit unsigned type, but Java does not have
    // an equivalent type. Casting an AnsiChar to a Byte leaves the value
    // as-is as 8 bits. Use a signed integer and limit its value to the
    // same range as a Byte...
    //
    return ((int)b) & 0xFF;
}

public static String EncryptePassword(String S, int Key)
{
    // in Delphi, Word is a 16-bit unsigned type, but Java does not have
    // an equivalent type. Use a signed integer and limit its value
    // to the same range as a Word...
    //
    if ((Key < 0) or (Key > 0xFFFF))
        throw new IllegalArgumentException("Key is outside the valid range of values");

    byte[] Str = S.getBytes(); // <-- you might need to specify a charset to get the correct bytes!
    int J;

    for(int I = 0; I < Str.length; ++I)
    {
        J = toUnsignedByte(Str[I]) ^ (Key >> 8);
        Str[I] := (byte) J;
        Key = ((toUnsignedByte(Str[I]) + Key) * C1 + C2) & 0xFFFF;
    }

    StringBuilder Result = new StringBuilder(Str.length * 3);

    for(int I = 0; I < Str.length; ++I)
    {
        Result.append(String.format(Locale.US, "%03d", toUnsignedByte(Str[I])));
    }

    return Result.toString();
}