1

So I tried to convert a piece of C# code to Java but I do not get same output when I use the converted code.

I already searched google and couldn't really find an answer. I' mostly interested in the Java equivalent of the TransformBlock method as I think that it is the one which causes problems.

C# code:

public class Sha256
{
    public Sha256()
    {
        sha = new SHA256Managed();
        sha.Initialize();
    }

    public void Process(byte[] data, int length)
    {
        sha.TransformBlock(data, 0, length, data, 0);
    }

    public void Process(uint data)
    {
        var bytes = BitConverter.GetBytes(data);

        sha.TransformBlock(bytes, 0, 4, bytes, 0);
    }

    public void Process(string data)
    {
        var bytes = Encoding.UTF8.GetBytes(data);

        sha.TransformBlock(bytes, 0, bytes.Length, bytes, 0);
    }

    public void Finish(byte[] data)
    {
        sha.TransformFinalBlock(data, 0, data.Length);

        Digest = sha.Hash;
    }

    public void Finish(byte[] data, int offset, int length)
    {
        sha.TransformFinalBlock(data, offset, length);

        Digest = sha.Hash;
    }

    SHA256 sha;
    public byte[] Digest { get; private set; }
}

Java code:

public class Sha256 {

    public byte[] digest;
    private MessageDigest sha;

    public Sha256() {
        try {
            sha = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException ex) {
            Logger.logException(ex);
        }
    }

    public void process(byte[] data, int length) {
        sha.update(data, 0, length);
    }

    public void process(int data) {
        byte[] bytes = ByteBuffer.allocate(Integer.BYTES).putInt(data).array();

        sha.update(bytes, 0, 4);
    }

    public void process(String data) {
        byte[] bytes = data.getBytes(StandardCharsets.UTF_8);

        sha.update(bytes, 0, bytes.length);
    }

    public void finish(byte[] data) {
        sha.update(data, 0, data.length);

        digest = sha.digest();
    }

    public void finish(byte[] data, int offset, int length) {
        sha.update(data, offset, length);

        digest = sha.digest();
    }

}
9
  • Can you post the Java code also? Commented Jul 18, 2018 at 11:10
  • You have many different method calls in there, each one of which could change when you port to Java. In any case, I don't think we can help you , because you didn't also show your Java code. Commented Jul 18, 2018 at 11:10
  • I posted the java code too Commented Jul 18, 2018 at 11:12
  • 2
    "I do not get same output" -- What do you get? What do you expect? For what input? Commented Jul 18, 2018 at 11:24
  • 1
    @PeterLawrey it seems that was the problem. Thanks. Commented Jul 18, 2018 at 13:54

1 Answer 1

1

C# is little endian by default AFAIK. This is most likely as it was developed by Microsoft who in turn used x86/x64 machines where little endian is the default.

Java's ByteBuffer uses big endian by default. It was first developed on SPARC processors which are big endian. There is couple of ways to swap the order of the bytes but the most natural is to use ByteBuffer.order() as below.

public void process(int data) {
    byte[] bytes = ByteBuffer.allocate(Integer.BYTES)
                             .order(ByteOrder.LITTLE_ENDIAN)
                             .putInt(data)
                             .array();

    sha.update(bytes, 0, bytes.length);
}
Sign up to request clarification or add additional context in comments.

Comments

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.