繁体   English   中英

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

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

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

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

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有谁知道我哪里出错了。 这不可能那么难,我想我现在只是没有看到它。

你快到了,但缺少一步:

对值(1 个字节)的传输类型(字符串或二进制)进行编码。

注意 逻辑数据类型 String 和 Number 使用 String 传输类型。

逻辑数据类型二进制使用二进制传输类型。

对于 String 传输类型,编码 1。

对于二进制传输类型,编码 2。

因此,您需要在 append 值前加上 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());

这是 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存储库中查看更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM