给定32字节md5字符串,如何获得n点的一致哈希/频谱

时间:2019-06-11 09:23:59

标签: string algorithm hash curve

我想对某些内容进行md5哈希处理,然后生成n点的“曲线”或“频谱”。也就是说,假设在0到1的直线上绘制5、10或20个点,其分布方式使它对于md5哈希是唯一的(冲突并不重要)。基本上看起来像是原子发光光谱。

enter image description here

enter image description here

这些点(或光谱中的线)是根据提供的md5哈希值以某种方式生成的,而n则提供了您要多少行的信息。

所以它就像:

function generateSpecrum(md5, n) { return [ ... ] }

默认情况下,它可能只返回0到1之间的值,但是也许您给它提供了一个起始值和结束值,即可从中产生范围。

想知道如何用伪代码或JS做到这一点。

但是,存在标准md5哈希的许多可能性。我会这样做:

var crypto = require('crypto')
var data = 'foo'
crypto.createHash('md5').update(data).digest('hex')
// acbd18db4cc2f85cedef654fccc4a4d8

是32字节的字符串。在我的情况下,它不需要产生全局唯一值,可能会发生一些冲突,但是如果有一种方法可以从不同的md5输入中产生各种光谱,那将很酷。

1 个答案:

答案 0 :(得分:3)

让我们忽略字符串数据为md5打印的部分,而将重点放在如何对任意长度的十六进制字符串执行此操作上,因此我们可以使用我们喜欢的任何摘要(从CRC32到SHA-512):

  1. 从色调渐变背景开始(我们可以在CSS中完成此操作)
  2. 将字符串转换为一点文字(内置到JS中),
  3. 涂黑对应于零位的任何区域。

作为可运行的代码段:

function hexstr2bin(stringinput) {
  // let's not be constrained by JS integer precision,
  // which is only good for 53 bits. Technically we don't
  // care what the "numbers" are here, we just want the
  // ones and zeros that the numbers turn into.
  return stringinput.split('').map(c => (
    parseInt(c, 16).toString(2).padStart(4,'0')
  )).join('');
}

function renderSpectrum(stringinput) {
  let cvs = document.createElement('canvas');
  let bits = Array.from(hexstr2bin(stringinput));

  cvs.width = bits.length;
  cvs.height = 1;
  ctx = cvs.getContext('2d');
  ctx.strokeStyle = 'black';
 
  bits.forEach( (bit,i) => {
    if (bit === "0") {
      ctx.moveTo(i,0);
      ctx.lineTo(i,1);
      ctx.stroke();
    }
  });

  document.body.appendChild(cvs);
};

renderSpectrum("acbd18db4fccc4a4d8");
renderSpectrum("c5887c91d0002f2a869a4b0772827701");
renderSpectrum("06956ff032d78e090d0d292aa9d8e7143ab08cf1ed444944529f79a4f937306a");
canvas {
  width: 100%;
  height: 40px;
  background: linear-gradient(
    to right,
    violet, blue, cyan, green, yellow, orange, red
  );
}

将画布拉伸到100%的宽度意味着您可以免费获得模糊效果。奖金!