首页 > 解决方案 > 为什么 HashAlgorithm.ComputeHash 从相同的数据返回不同的值?

问题描述

我想从邮递员发送的数据中创建哈希。我发送了一些数据并且它工作,它被添加到数据库中。但是,当我接下来想发布一些东西时,我在数据库中的 Shipment 会被验证它的哈希是否正确,然后保存在数据库中的哈希与计算的不同。当我从邮递员发布数据和从数据库读取数据时有什么区别吗?

public class BlockExtension : IBlock
{
    public byte[] CalculateHash(Shipment shipment)
    {
        var dataToHash = new DataToHash(shipment.Data, shipment.index, shipment.PrevHash, shipment.TimeStamp);

        using (SHA256 hash = SHA256.Create())
        {
            Encoding enc = Encoding.UTF8;
            Byte[] result = hash.ComputeHash(ObjectToByteArray(dataToHash));

            return result;
        }
    }

    private byte[] ObjectToByteArray(DataToHash data)
    {
        if (data == null)
            return null;

        var options = new JsonSerializerOptions()
        {
            ReferenceHandler = ReferenceHandler.Preserve
        };

        var result = JsonSerializer.SerializeToUtf8Bytes(data, options);
        return result;
    }

    public Shipment CreateGenesisBlock(CreateShipmentCommand request)
    {
        var block = new Shipment()
        {
            ProductId = request.ProductId,
            index = 0,
            TimeStamp = DateTime.Now,
            PrevHash = BitConverter.GetBytes('0'),
            Data = new Data()
            {
                PlaceOfArrivalId = request.Data.PlaceOfArrivalId,
                PlaceOfDepartureId = request.Data.PlaceOfDepartureId
            }
        };

        block.Hash = CalculateHash(block);

        return block;
    }

    public Shipment GetLatestBlock(Product product) => product.SupplyChain.Last();

    public bool IsChainValid(List<Shipment> shipments)
    {
        for (var i = 1; i < shipments.Count; i++)
        {
            var currentBlock = shipments[i];
            var previousBlock = shipments[i - 1];


            if (!(currentBlock.Hash.SequenceEqual(CalculateHash(currentBlock))))
            {
                return false;
            }

            if (!currentBlock.PrevHash.SequenceEqual(previousBlock.Hash))
            {
                return false;
            }
        }

        return true;
    }

    public List<Shipment> AddBlock(Shipment shipment, Product product)
    {
        shipment.PrevHash = GetLatestBlock(product).Hash;
        shipment.Hash = CalculateHash(shipment);
        product.SupplyChain.Add(shipment);

        return product.SupplyChain.ToList();
    }
}

在此处输入图像描述

标签: c#.net-corehashblockchain

解决方案


推荐阅读