0

Delphi and Java are generate totally different values.

I have MD5 list and I need to encode them with Base64 then URLEncode.

Here is the delphi and java output of the same hash values.

How can I get same as Java output with Delphi?

MD5 Input Value:

BB8C890E3E6372F2720709262BD42BF4

Java Base64 Encoded Output Value :

vIRYPbGf3toJDQehgv3SOamnTNk=

Delphi Base64 Encoded Output Value:

QkI4Qzg5MEUzRTYzNzJGMjcyMDcwOTI2MkJENDJCRjQ=

The delphi code line is:

IdEncoderMIME1.EncodeString('BB8C890E3E6372F2720709262BD42BF4');

And the Java Source is:

String md5 = new String(Base64.encodeBase64(decodedHex));

Full Java Code (That I want to have same results with Delphi): public static void main(String[] args) throws Exception { if ( args.length != 8 ) { usage(); return; }

WebClient webClient = null;

try
{
byte[] decodedHex = Hex.decodeHex(args[0].toCharArray());

String sha1 = new String(Base64.encodeBase64(decodedHex));

decodedHex = Hex.decodeHex(args[1].toCharArray());

String md5 = new String(Base64.encodeBase64(decodedHex));

String rep = args[2];
String comment = args[3];
String Server = args[4];
String ServerPort = args[5];
String username = args[6];
String password = args[7];

String params = "[{\"sha1\":\"" + sha1 + "\",\"md5\":\"" + md5 + "\",\"rep\":\"" + rep + "\",\"comment\":\"" + comment + "\"}]";

// Note the usage of URLEncoder to ensure special characters can be used within the parameters.
String url = "https://" + Server + ":" + ServerPort + "/setRep?fileReps=" + URLEncoder.encode(params, "UTF-8");

System.out.println("\nWeb API params with Base64 values but are not yet URL encoded:");
System.out.println("\n" + params + "\n");
System.out.println("\nWeb API URL call with URL encoded parameters:");
System.out.println("\n" + url + "\n");

webClient = new WebClient(BrowserVersion.FIREFOX_24);

webClient.getOptions().setUseInsecureSSL(true);

DefaultCredentialsProvider userCredentials = (DefaultCredentialsProvider)webClient.getCredentialsProvider();
userCredentials.addCredentials(username, password);
webClient.setCredentialsProvider(userCredentials);

Page setFileRepResponsePage = webClient.getPage(url);

String pageResponse = setFileRepResponsePage.getWebResponse().getContentAsString();

System.out.println("HTTP Status code: " + setFileRepResponsePage.getWebResponse().getStatusCode());
System.out.println(pageResponse);

}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
try
{
webClient.closeAllWindows();
}
catch(Exception ex) {}
}
}
3
  • What code are you using to convert it? Commented Feb 17, 2015 at 13:14
  • 1
    The problem can be found in your code, which only you can see. We might guess that you are getting confused between encoding the binary hash5 and its hex representation. Of course, only you can possibly how you want to encode this. So, what are you trying to do? Commented Feb 17, 2015 at 13:25
  • I use this line : IdEncoderMIME1.EncodeString('BB8C890E3E6372F2720709262BD42BF4'); Commented Feb 17, 2015 at 14:09

2 Answers 2

2
IdEncoderMIME1.EncodeString('BB8C890E3E6372F2720709262BD42BF4');

This takes text input, encodes as ASCII, and then encodes as base64.

String md5 = new String(Base64.encodeBase64(decodedHex));

This takes the binary data in decodedHex and encodes as base64.

As such, your two pieces of code are doing different things. In order for you to make any progress you really need to work out what you want to do. In my view, it makes no sense to take a binary hash, encode as hex, encode as ASCII and then encode as base64.

So I would say that the Delphi code is the problem. You start from the binary hash and base64 encode that. I cannot give you code to do this because you have not given us enough code to work with. For instance, I'm pretty sure that you don't start with 'BB8C890E3E6372F2720709262BD42BF4' as a string literal.

But really your main task here is not to write code, but to get a firm grip on what encodings you should be performing.

FWIW, this confusion between text and binary is one of the great recurring themes in the Delphi tag. I guess it all stemmed from the habit that Delphi programmers adopted of using string as if it were a byte array. This blurring of the distinction between text and binary leads to methods like TIdEncoderMIME.EncodeString which encourages you to think, erroneously, that base64 encoding operates on textual input.


According to your latest edit you wish to decode the hex string to binary, and base64 encode that. Which is done like so in Delphi:

uses
  System.Classes,
  System.NetEncoding;

function HexStringToBase64(const HexStr: string): string;
var
  md5bytes: TBytes;
begin
  SetLength(md5Bytes, Length(HexStr) div 2);
  HexToBin(PChar(HexStr), Pointer(md5Bytes), Length(md5Bytes));
  Result := TNetEncoding.Base64.EncodeBytesToString(md5Bytes);
end;

Now, you won't have TNetEncoding unless you are using XE7 or later. If that is so, choose another base64 library. If you prefer to use the Indy encoder then you'd write it like this:

function HexStringToBase64(const HexStr: string): string;
var
  md5bytes: TIdBytes;
begin
  SetLength(md5Bytes, Length(HexStr) div 2);
  HexToBin(PChar(HexStr), Pointer(md5Bytes), Length(md5Bytes));
  Result := TIdEncoderMIME.EncodeBytes(md5Bytes);
end;

And FWIW, your Java code does not produce the output that you claim it does.

Sign up to request clarification or add additional context in comments.

9 Comments

A totally agree with you. This convert issue is not necessary but I use a Product API to handle some tasks and the API wanted to have binary encoded MD5 hashes to do these tasks. This code part is simply generate an MD5 hashes from the files and stores them into Memo. I need to pass those MD5 hashes to program WebAPI as binary base64 encoded value.
You need to keep working on trying to understand what I am telling you. You don't appear to appreciate the difference between text and binary.
I really don't understand. Do I need to convert MD5 hash string value to binary, and how?
You need to decide what you want to do. I cannot tell you what you want to do. I can only see tiny fragments of your code and I've really got no idea what the goal is. There's certainly no way for any of here to be able to show you how to replicate the Java code until you actually show it.
The goal is converting Md5 values into binary encoded base64 values. Thats all.
|
2
package main;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class test {
    public static void main(String[] args) {
        try {
            // outputs QkI4Qzg5MEUzRTYzNzJGMjcyMDcwOTI2MkJENDJCRjQ=
            System.out.println(Base64.getEncoder()
                .encodeToString("BB8C890E3E6372F2720709262BD42BF4".getBytes("US-ASCII")));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}

2 Comments

@DavidHeffernan now you mention it... xD
I think I am not clear enough. I am going to add Delphi and Java code together. I want to have same result with Delphi. I can have code that java produce the output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.