AWS SQS,如何计算消息属性的 MD5 消息摘要

AWS SQS, How to calculate the MD5 message digest for message attributes

我目前正在尝试弄清楚如何计算 AWS 中消息属性的 MD5 消息摘要。 我正在关注 uri SQS message metadata > 计算消息属性的 MD5 消息摘要

虽然这看起来很简单,但我正在尝试获取以下属性的哈希值

var messageAttributes = new Dictionary<string, MessageAttributeValue>
{
    {"UserName", new MessageAttributeValue {DataType ="String", StringValue = "Me"}}
};

我已发送此消息,MD5 响应是 3a6071d47534e3e07414fea5046fc217

试图找出文档我认为这应该可以解决问题:

private void CustomCalc()
{
    var verifyMessageAttributes = new List<byte>();
    verifyMessageAttributes.AddRange(EncodeString("UserName"));
    verifyMessageAttributes.AddRange(EncodeString("String"));
    verifyMessageAttributes.AddRange(EncodeString("Me"));
    var verifyMessageAttributesMd5 = GetMd5Hash(verifyMessageAttributes.ToArray());
}

private List<byte> EncodeString(string data)
{
    var result = new List<byte>();
    if (BitConverter.IsLittleEndian)
    {
        result.AddRange(BitConverter.GetBytes(data.Length).Reverse());
    }
    else
    {
        result.AddRange(BitConverter.GetBytes(data.Length));
    }
    result.AddRange(Encoding.UTF8.GetBytes(data));
    return result;

}
public static string GetMd5Hash(byte[] input)
{
    using (var md5Hash = MD5.Create())
    {
        // Convert the input string to a byte array and compute the hash.
        var dataBytes = md5Hash.ComputeHash(input);

        // Create a new string builder to collect the bytes and create a string.
        var sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data and format each one as a hexadecimal string.
        foreach (var dataByte in dataBytes)
        {
            sBuilder.Append(dataByte.ToString("x2"));
        }

        // Return the hexadecimal string.
        return sBuilder.ToString();
    }
}

但我最终得到了这个 cf886cdabbe5576c0ca9dc51871d10ae 有谁知道我要去哪里错了。应该没有那么难吧,我想我只是现在没看到而已。

您快完成了,但还差一步:

Encode the transport type (String or Binary) of the value (1 byte).

Note The logical data types String and Number use the String transport type.

The logical data type Binary uses the Binary transport type.

For the String transport type, encode 1.

For the Binary transport type, encode 2.

因此您需要在值前附加 1 或 2,以指示传输类型。你的情况:

var verifyMessageAttributes = new List<byte>();
verifyMessageAttributes.AddRange(EncodeString("UserName"));
verifyMessageAttributes.AddRange(EncodeString("String"));
verifyMessageAttributes.Add(1); // < here
verifyMessageAttributes.AddRange(EncodeString("Me"));
var verifyMessageAttributesMd5 = GetMd5Hash(verifyMessageAttributes.ToArray());

这是 stand-alone Node.js 中的解决方案:

const md5 = require('md5');

const SIZE_LENGTH = 4;
const TRANSPORT_FOR_TYPE_STRING_OR_NUMBER = 1;
const transportType1 = ['String', 'Number'];

module.exports = (messageAttributes) => {
  const buffers = [];
  const keys = Object.keys(messageAttributes).sort();

  keys.forEach((key) => {
    const { DataType, StringValue } = messageAttributes[key];

    const nameSize = Buffer.alloc(SIZE_LENGTH);
    nameSize.writeUInt32BE(key.length);

    const name = Buffer.alloc(key.length);
    name.write(key);

    const typeSize = Buffer.alloc(SIZE_LENGTH);
    typeSize.writeUInt32BE(DataType.length);

    const type = Buffer.alloc(DataType.length);
    type.write(DataType);

    const transport = Buffer.alloc(1);

    let valueSize;
    let value;
    if (transportType1.includes(DataType)) {
      transport.writeUInt8(TRANSPORT_FOR_TYPE_STRING_OR_NUMBER);
      valueSize = Buffer.alloc(SIZE_LENGTH);
      valueSize.writeUInt32BE(StringValue.length);

      value = Buffer.alloc(StringValue.length);
      value.write(StringValue);
    } else {
      throw new Error(
        'Not implemented: MessageAttributes with type Binary are not supported at the moment.'
      );
    }

    const buffer = Buffer.concat([nameSize, name, typeSize, type, transport, valueSize, value]);

    buffers.push(buffer);
  });

  return md5(Buffer.concat(buffers));
};

GitHub

上的 sqslite 存储库中查看更多内容