2016-10-28 2 views
0

У меня есть этот Delphi кодПреобразование Delphi в Java (мой код правильно?)

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

Не сворачивайте свое собственное шифрование, вы НЕ ПОЛУЧИЛИ это неправильно и вызывают дыру в безопасности. Используйте одну из многих библиотек, доступных в java. –

+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-разрядный Анси строка, но в Delphi 2009, а затем это 16-разрядная строка Unicode. Строки Java - это 16-разрядный Unicode. Вы не сказали, какая версию Delphi вы пытаетесь портировать код с, но если это версия Анси то перевод может выглядеть следующим образом, вместо:

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(); 
} 
Смежные вопросы