首页 > 解决方案 > 将 C# 代码转换为 Java

问题描述

所以我尝试将一段 C# 代码转换为 Java,但是当我使用转换后的代码时,我没有得到相同的输出。

我已经搜索了谷歌并无法真正找到答案。我最感兴趣的是 Java 等效的 TransformBlock 方法,因为我认为它是导致问题的方法。

C#代码:

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代码:

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();
    }

}

标签: javac#

解决方案


默认情况下,C# 是小端 AFAIK。这很可能是因为它是由 Microsoft 开发的,而 Microsoft 又使用 x86/x64 机器,其中 little endian 是默认设置。

Java 的 ByteBuffer 默认使用大端。它最初是在大端的 SPARC 处理器上开发的。有几种方法可以交换字节顺序,但最自然的是ByteBuffer.order()如下使用。

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

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

推荐阅读