Link to home
Create AccountLog in
Avatar of Connie McBride
Connie McBride

asked on

Delphi Ansichar to Java char

I have code that does some simple encryption in delphi, has been in place for eons.
Now I need to create a java function to decrypt it, and can't seem to figure out how it needs to work, since my java decryption logic, based on my delphi logic, is returning odd characters.

mostly the java verson works - up to a point.

if the character being converted is 'r' and aBit is 34, the java code does not decrypt correctly.

Delphi encryption:(aBit is an interger)
   result := AnsiChar(byte(ord(aStr)) + aBit);

Open in new window


Delphi Decrypt:
result := AnsiChar(byte(ord(aStr)) - aBit);

Open in new window

 
java decrypt:

String str = aString ;
if (str != null)
{
char[] chars = str.toCharArray();
String temp = "";

for (int i = 0; i < chars.length; i++)
{
char temp0 =(char)((int)chars[i] - str.length());
temp += temp0;
}
return temp;
}
else
{
return null;

}

Open in new window

Avatar of Beneford
Beneford
Flag of United Kingdom of Great Britain and Northern Ireland image

Isn't the java char data type 16 bits? (and strings are strings of UTF-16).
I'm assuming your old Delphi code only cares about 8-bit characters.
In this case, you probably need to prevent any char values outside 0xff.

If you change line 9 to:
char temp0 =(char)(((int)chars[i] - str.length()) & 0xff);

Open in new window

Does that do any good?

(btw, you can probably speed things up by using a variable l for str.length() and using that for chars.length)
Avatar of Connie McBride
Connie McBride

ASKER

better, but changed to û instead of r, so not quite there yet
Another problem you may have is that reading the encrypted text (which has characters in the range 0x00-0xff) into a java string, you may not be getting the character encoding you had expected.
Have you verified that the array is exactly what you expected it to be?

For example, in Ascii, û is =150 (0x96) but in Unicode/UTF16 it is 0xFB.
If Java is doing a conversion from some code page when reading in the encrypted text, you'll probably get some wrong answers.
Is it possible to do the decryption without using strings at all?

Or can you use something like:
str.getBytes("US-ASCII")
Is it possible to do the decryption without using strings at all?
not sure what you mean.  a string is coming in to be decrypted.

(using byte instead of char also did not work.  could be I don't understand, don't know java all that well)

my unit test
   @Test
   public void testVerifyStr()
   {
      System.out.println("verifyStr");
      String aString = "ufmOvivOTSWOdtiV”™ˆUd›ZXriˆ‹ksy|xc";
      String expResult = "SDK-TGT-215-BRG4rwf3By86PGfiIQWZVA";
      String result = globals.verifyStr(aString);
      assertEquals(expResult, result);

Open in new window

my function (latest attempt)

public static String verifyStr(String str)
   {
      char temp0;
      byte[] chars;
      String temp = "";
      Integer l;
      int c;
	   if (str != null)
      {
         try
         {
            l = str.length();
            chars = str.getBytes("US-ASCII");
            for (int i = 0; i < l; i++)
            {
               c =  ((int)chars[i] - l);
               temp0 =(char) c;
               temp += temp0;
            }
         }
         catch (Exception ex)
         {
            Logger.getLogger(globals.class.getName()).log(Level.SEVERE, null, ex);
         }
         return temp;
       }
      else
      {
	       return null;

      }
   }

Open in new window


the string to decrypt was generated through Delphi as an AnsiString and stored on mssql server

result := AnsiChar(byte(ord(aStr)) + aBit); (character conversion)
Can you run a little test on your data?
You've only got 34 characters, and it would be instructive to see the value of the chars array.
They should be:
117      102      109      79      118      105      118      79      84
83      87      79      100      116      105      86      148      153
136      85      100      155      90      88      114      105      136
139      107      115      121      124      120      99

But I'm wondering if they really are.
When you get outside characters 32-127, odd things can happen. In this case, it looks like SQLServer is storing them correctly and retrieving them correctly, but I'm not sure that Java is handling them correctly.
US-ASCII may be the wrong collating sequence.
You could try getBytes( "UTF-8" ) or getBytes( "ISO-8859-1" )
There are some other charsets documented here: http://docs.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html

As you can see, the character that needs to become 'r' is the first one that is > 127 (148).
Using US-Ascii, I get
112, 102, 109, 79, 118, 105 118, 79, 84,
83, 87, 79, 100, 116, 105, 86,
63, 63, 63 ---first one should be 'r', next 2 (should be 'w' and 'f')also have issues, solve for one, solve for all...

UTF-8
same, until 'r'
-30, -128, -60

ISO-8859-1
Same as US-Ascii

UTF-16BE
0, 117, 0, 102...(obviously not right)
UTF-16LE
117, 0, 102, 0 (also obviously not right)
UTF-16
-2, -1, 0, 117 (again, not right)
Do you know what your SQL server's collating sequence is for the table containing the codes?

UTF-8 looks like it might work, but you need to find out how to convert from the codes you're getting to the codes you need.

It's probably a look-up conversion rather than a formula.
Create an array and fill in the numbers as you work them out:
convert[256- 30]=148
convert[256-128]=153
convert[256- 60]=136
...

Open in new window

btw, using nothing, I get

-108, -103, and -120 for those three characters (r, w, f)
Using nothing is good - just a different conversion table.
As long as you're consistent you should be OK.

But do be aware you're relying on character encodings and collating sequences and if they change in the future, you may get problems in the future.
sql server collation (on my system) is SQL_Latin1_General_CP1_CI_AS
we have several customers, and it is possible that it could be different per site
ASKER CERTIFIED SOLUTION
Avatar of Beneford
Beneford
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
awesome!  thank you.