我有这个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代码吗?
答案 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();
}