简体   繁体   English

无法复制字符串的散列

[英]Can't replicate hashing of string

I need to reproduce a JS function that hashes a string with SHA-256 in r.我需要重现一个 JS 函数,该函数在 r 中使用 SHA-256 散列字符串。
The said function is:所说的功能是:

function hashPhrase (phrase) {
  const buf = new ArrayBuffer(phrase.length * 2)
  const bufView = new Uint16Array(buf)
  const strLen = phrase.length
  for (let i = 0; i < strLen; i++) {
    bufView[i] = phrase.charCodeAt(i)
  }
  return window.crypto.subtle.digest('SHA-256', buf)
    .then(hashArrayBuffer => {
      let binary = ''
      const bytes = new Uint8Array(hashArrayBuffer)
      const len = bytes.byteLength
      for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i])
      }
      return Promise.resolve(window.btoa(binary))
    })
}

Calling the function:调用函数:

hashPhrase('test').then(x => { console.log(x) })

gives me:给我:

/lIGdrGh2T2rqyMZ7qA2dPNjLq7rFj0eiCRPXrHeEOs=

as output.作为输出。

I load openssl and try to use sha256 as function to hash the string.我加载 openssl 并尝试使用 sha256 作为函数来散列字符串。

library(openssl)

phrase = "test"
phraseraw = charToRaw(phrase)
base64_encode(sha256(phraseraw))

and the output is:输出是:

[1] "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg="

Don't know if the problem is the uint16 because in both cases I guess that the variable is being passed as raw.不知道问题是否出在 uint16 上,因为在这两种情况下,我猜变量是作为原始值传递的。

I'll appreciate very much any help.我将非常感谢任何帮助。

Because you created an Uint16Array, you are using two bytes per character and those values are presumably being stored in little-endian byte order.因为您创建了一个 Uint16Array,所以每个字符使用两个字节,并且这些值可能以 little-endian 字节顺序存储。 By default in R, since you just have ASCII characters, it is just using one byte per character.默认情况下,在 R 中,由于您只有 ASCII 字符,因此每个字符仅使用一个字节。 So with javascript you are digesting the bytes所以使用 javascript 你正在消化字节

[116, 0, 101, 0, 115, 0, 116, 0]

But with the R code you are digesting the bytes.但是使用 R 代码,您正在消化字节。

[116, 101, 115, 116]

If you really want to include those padded values in R like you do in javascript, you can convert to UTF16-LE before the digest如果您真的想像在 javascript 中那样在 R 中包含这些填充值,则可以在摘要之前转换为 UTF16-LE

phrase = "test"
phraseraw = iconv(phrase,from="ASCII", to="UTF-16LE",toRaw = TRUE)[[1]]
base64_encode(sha256(phraseraw))
# [1] "/lIGdrGh2T2rqyMZ7qA2dPNjLq7rFj0eiCRPXrHeEOs="

So really just make sure you are encoding your string into bytes in the exact same way in both languages.所以真的只是确保你在两种语言中以完全相同的方式将字符串编码为字节。

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

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