Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/469.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将哈希字符串从C转换为JS_Javascript_C++_C_Firefox Addon - Fatal编程技术网

Javascript 将哈希字符串从C转换为JS

Javascript 将哈希字符串从C转换为JS,javascript,c++,c,firefox-addon,Javascript,C++,C,Firefox Addon,我试图从Mozilla Firefox代码库转换此函数,它名为HashString。它调用了一组函数,这些函数都在这个文件中: 下面是它调用的C函数: static const uint32_t kGoldenRatioU32 = 0x9E3779B9U; MOZ_WARN_UNUSED_RESULT inline uint32_t HashString(const wchar_t* aStr) { return detail::HashUntilZero(aStr); } templa

我试图从Mozilla Firefox代码库转换此函数,它名为
HashString
。它调用了一组函数,这些函数都在这个文件中:

下面是它调用的C函数:

static const uint32_t kGoldenRatioU32 = 0x9E3779B9U;

MOZ_WARN_UNUSED_RESULT inline uint32_t
HashString(const wchar_t* aStr)
{
  return detail::HashUntilZero(aStr);
}

template<typename T>
uint32_t
HashUntilZero(const T* aStr)
{
  uint32_t hash = 0;
  for (T c; (c = *aStr); aStr++) {
    hash = AddToHash(hash, c);
  }
  return hash;
}

MOZ_WARN_UNUSED_RESULT inline uint32_t
AddToHash(uint32_t aHash, A* aA)
{
  /*
   * You might think this function should just take a void*.  But then we'd only
   * catch data pointers and couldn't handle function pointers.
   */

  static_assert(sizeof(aA) == sizeof(uintptr_t), "Strange pointer!");

  return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, uintptr_t(aA));
}

inline uint32_t
AddUintptrToHash<8>(uint32_t aHash, uintptr_t aValue)
{
  /*
   * The static cast to uint64_t below is necessary because this function
   * sometimes gets compiled on 32-bit platforms (yes, even though it's a
   * template and we never call this particular override in a 32-bit build).  If
   * we do aValue >> 32 on a 32-bit machine, we're shifting a 32-bit uintptr_t
   * right 32 bits, and the compiler throws an error.
   */
  uint32_t v1 = static_cast<uint32_t>(aValue);
  uint32_t v2 = static_cast<uint32_t>(static_cast<uint64_t>(aValue) >> 32);
  return AddU32ToHash(AddU32ToHash(aHash, v1), v2);
}

inline uint32_t
AddU32ToHash(uint32_t aHash, uint32_t aValue)
{
  return kGoldenRatioU32 * (RotateBitsLeft32(aHash, 5) ^ aValue);
}

inline uint32_t
RotateBitsLeft32(uint32_t aValue, uint8_t aBits)
{
  MOZ_ASSERT(aBits < 32);
  return (aValue << aBits) | (aValue >> (32 - aBits));
}
静态常数uint32\u t kGoldenRatioU32=0x9E3779B9U;
MOZ_WARN_UNUSED_结果内嵌uint32_t
哈希字符串(常量wchar\u t*aStr)
{
返回详细信息::HashUntilZero(aStr);
}
模板
uint32\u t
HashUntilZero(常数T*aStr)
{
uint32\u t hash=0;
for(tc;(c=*aStr);aStr++){
hash=AddToHash(hash,c);
}
返回散列;
}
MOZ_WARN_UNUSED_结果内嵌uint32_t
AddToHash(uint32_t aHash,A*aA)
{
/*
*你可能会认为这个函数应该是一个空的*,但是我们只需要
*捕获数据指针,但无法处理函数指针。
*/
静态断言(sizeof(aA)=sizeof(uintpttr\u t),“奇怪的指针!”);
返回细节::AddUintptrToHash(aHash,uintpttr_t(aA));
}
内联uint32\u t
AddUintptrToHash(uint32\u t aHash,uintpttr\u t aValue)
{
/*
*以下uint64的静态强制转换是必要的,因为此功能
*有时在32位平台上编译(是的,尽管它是一个
*我们在32位构建中从不调用此特定重写)。如果
*我们在32位机器上执行aValue>>32,我们正在移动32位uintptr\t
*右转32位,编译器将抛出一个错误。
*/
uint32_t v1=静态播放(aValue);
uint32\u t v2=静态播放(静态播放(aValue)>>32);
返回AddU32ToHash(AddU32ToHash(aHash,v1),v2);
}
内联uint32\u t
addu32-tohash(uint32-aHash,uint32-aValue)
{
返回kGoldenRatioU32*(RotateBitsLeft32(aHash,5)^aValue);
}
内联uint32\u t
RotateBitsLeft32(uint32可用,uint8可用)
{
MOZ_断言(aBits<32);
返回(aValue>(32-aBits));
}
这是我的js代码:

function HashString(aStr, aLength) {
    // moz win32 hash function

    if (aLength) {
        console.error('NS_ERROR_NOT_IMPLEMENTED');
        throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
    } else {
        return HashUntilZero(aStr);
    }   
}

function HashUntilZero(aStr) {
    var hash = 0;
    //for (T c; (c = *aStr); aStr++) {
    for (var c=0; c<aStr.length; c++) {
        hash = AddToHash(hash, aStr.charCodeAt(c));
    }

    return hash;
}

function AddToHash(aHash, aA) {
    //return detail::AddU32ToHash(aHash, aA);
    //return AddU32ToHash(aHash, aA);

    //return detail::AddUintptrToHash<sizeof(uintptr_t)>(aHash, aA);
    return AddUintptrToHash(aHash, aA);
}

function AddUintptrToHash(aHash, aValue) {
    //return AddU32ToHash(aHash, static_cast<uint32_t>(aValue));
    return AddU32ToHash(aHash, aValue);
}

function AddU32ToHash(aHash, aValue) {
    var kGoldenRatioU32 = 0x9E3779B9;
    return (kGoldenRatioU32 * (RotateBitsLeft32(aHash, 5) ^ aValue));
}

function RotateBitsLeft32(aValue, aBits) {
    // MOZ_ASSERT(aBits < 32);
    return (aValue << aBits) | (aValue >> (32 - aBits));
}

console.log(HashString('C:\Users\Vayeate\AppData\Roaming\Mozilla\Firefox\Profiles\aksozfjt.Unnamed Profile 10')); // should return 3181739213
函数哈希字符串(aStr,aLength){
//moz win32哈希函数
if(aLength){
console.error('NS_error_NOT_IMPLEMENTED');
抛出组件.results.NS\u错误\u未实现;
}否则{
返回HashUntilZero(aStr);
}   
}
函数HashUntilZero(aStr){
var散列=0;
//for(tc;(c=*aStr);aStr++){
对于(VarC=0;c(32-aBits));
}
log(HashString('C:\Users\Vayeate\AppData\Roaming\Mozilla\Firefox\Profiles\aksozfjt.Unnamed Profile 10');//应返回3181739213

执行HashString('C:\Users\Vayeate\AppData\Roaming\Mozilla\Firefox\Profiles\aksozfjt.Unnamed Profile 10')时,这不正常<代码>应该返回给我<代码> 3181739213代码>但是它不是。它继续返回给我:<代码> -159266146140 < /Cord>

< P> >让我们先实现一个更为简单的C++版本,它还可以卸载我们稍后比较的中间值。
#include <iostream>
#include <iomanip>
#include <stdint.h>

using namespace std;

static const uint32_t gr = 0x9E3779B9U;
template<typename T>
static uint32_t add(uint32_t hash, T val) {
  const uint32_t rv = gr * (((hash << 5) | (hash >> 27)) ^ val);
  cerr << dec << setw(7) << (uint32_t)val << " " << setw(14) << rv << " " << hex << rv << endl;
  return rv;
}

int main() {
  const auto text = string("C:\\Users\\Vayeate\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\aksozfjt.Unnamed Profile 10");
  uint32_t rv = 0;
  for (auto c: text) {
    rv = add(rv, c);
  }
  cout << "Result: " << dec << setw(14) << rv << " " << hex << rv << endl;
}
可能不是最有效的实现,但至少它可以工作;)

有一种更简单的方法

var file = new FileUtils.File('C:\\Users\\Vayeate\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\aksozfjt.Unnamed Profile 10');
file.QueryInterface(Ci.nsIHashable);
console.log(file.hashCode === 3181739213);

在您位于
HashUntillZero
的for循环中,您正在递增字符串而不是计数器,这会弄乱其余的代码。啊,非常感谢@entorarox!我错过了它,我已经修复了它,但现在它在我应该得到
3181739213
时给了我
-159266146140
:(您也没有复制黄金比例的最后一个十六进制,但这是一个相当容易的错误,我自己第一次就错过了。编辑:C++/C可能处理右移的方式与javascript不同,但我可以确定。C:
static const uint32\u t kGoldenRatioU32=0x9E3779B9U;
,JS:
var kGoldenRatioU32=0x9e379b9;
我已经检查了类型声明,我相信问题就在那里,javascript没有无符号的32位整数,只有有符号的,您必须将有符号的32位整数转换为普通的javascript
number
(因为这不受32位的限制)在
AddU32ToHash
Right中使用它之前…
nsIFile
nsifhash
,很好的捕获。所以对于
nsIFile
兼容的路径,这个路径可以很好地工作,而且确实更简单。嘿,paa和@nmaier,当我复制粘贴这个代码时,它会给我
3375393251
它应该是
3181739213
,我确信关于这一点,因为这是我的个人资料的
browser.taskbar.lastgroupid
值。这真的很奇怪。你知道怎么回事吗?hashCode是3181739213。可能lastgroupid不包含hashCode的值。@Noitidart,nmaier的实现和nsIHashable都返回相同的结果,至少示例中是这样。和即使它们是不同的,我也怀疑故障是在NsihhAsple的边上的。您所指的代码显示了路径的散列串是有条件使用的。您的代码是否考虑了这些条件?在我的系统中,它返回了3181739213。另一方面,在我的系统上,这个路径不存在。您可以检查代码是否为<代码>:\\用户\\未知\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\aksozfjt.Unnamed Profile 10是3103912233吗?
var file = new FileUtils.File('C:\\Users\\Vayeate\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\aksozfjt.Unnamed Profile 10');
file.QueryInterface(Ci.nsIHashable);
console.log(file.hashCode === 3181739213);