2010-11-20 17 views
2

Kullanabileceğim Jenkins Hash'un kendi başıma uygulamaktan çok javascript uygulaması var mı?Javascript uygulaması?

Kendi j'leri yazmak için kullanabileceğim bir python uygulaması olduğunu biliyorum. Ama ben Javascript uzmanı değilim ve bunun için birisinin elses uygulamasını tercih ederim.


Güncelleme: (ı dönüştürmek çalıştım http://www.burtleburtle.net/bob/c/lookup3.c) Güncelleme 2: Bu kod sadece birkaç ile lookup3.c

var Jenkins = { 
rot: function(x,k) { 
    return (x<<k) | (x>>>(32-k)); 
}, 

mix: function(a,b,c) { 
    a = (a - c) | 0; a ^= Jenkins.rot(c, 4); c = (c + b) | 0; 
    b = (b - a) | 0; b ^= Jenkins.rot(a, 6); a = (a + c) | 0; 
    c = (c - b) | 0; c ^= Jenkins.rot(b, 8); b = (b + a) | 0; 
    a = (a - c) | 0; a ^= Jenkins.rot(c,16); c = (c + b) | 0; 
    b = (b - a) | 0; b ^= Jenkins.rot(a,19); a = (a + c) | 0; 
    c = (c - b) | 0; c ^= Jenkins.rot(b, 4); b = (b + a) | 0; 
    return {a : a, b : b, c : c}; 
}, 

final: function(a,b,c) { 
    c ^= b; c -= Jenkins.rot(b,14) | 0; 
    a ^= c; a -= Jenkins.rot(c,11) | 0; 
    b ^= a; b -= Jenkins.rot(a,25) | 0; 
    c ^= b; c -= Jenkins.rot(b,16) | 0; 
    a ^= c; a -= Jenkins.rot(c,4) | 0; 
    b ^= a; b -= Jenkins.rot(a,14) | 0; 
    c ^= b; c -= Jenkins.rot(b,24) | 0; 
    return {a : a, b : b, c : c}; 
}, 

hashlittle2: function(k, initval, initval2) { 
    var length = k.length; 
    a = b = c = 0xdeadbeef + length + initval; 
    c += initval2; 

    offset = 0; 
    while (length > 12) { 
     a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); a = a>>>0; 
     b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16) + (k.charCodeAt(offset+7)<<24)); b = b>>>0; 
     c += (k.charCodeAt(offset+8) + (k.charCodeAt(offset+9)<<8) + (k.charCodeAt(offset+10)<<16) + (k.charCodeAt(offset+11)<<24)); c = c>>>0; 
     o = Jenkins.mix(a,b,c); 
     a = o.a; b = o.b; c = o.c; 
     length -= 12; 
     offset += 12; 
    } 

    switch(length) { 
     case 12: c += (k.charCodeAt(offset+8) + (k.charCodeAt(offset+9)<<8) + (k.charCodeAt(offset+10)<<16) + (k.charCodeAt(offset+11)<<24)); b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16) + (k.charCodeAt(offset+7)<<24)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 11: c += (k.charCodeAt(offset+8) + (k.charCodeAt(offset+9)<<8) + (k.charCodeAt(offset+10)<<16)); b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16) + (k.charCodeAt(offset+7)<<24)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 10: c += (k.charCodeAt(offset+8) + (k.charCodeAt(offset+9)<<8)); b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16) + (k.charCodeAt(offset+7)<<24)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 9: c += (k.charCodeAt(offset+8)); b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16) + (k.charCodeAt(offset+7)<<24)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 8: b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16) + (k.charCodeAt(offset+7)<<24)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 7: b += (k.charCodeAt(offset+4) + (k.charCodeAt(offset+5)<<8) + (k.charCodeAt(offset+6)<<16)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 6: b += ((k.charCodeAt(offset+5)<<8) + k.charCodeAt(offset+4)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 5: b += (k.charCodeAt(offset+4)); a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 4: a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16) + (k.charCodeAt(offset+3)<<24)); break; 
     case 3: a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8) + (k.charCodeAt(offset+2)<<16)); break; 
     case 2: a += (k.charCodeAt(offset+0) + (k.charCodeAt(offset+1)<<8)); break; 
     case 1: a += (k.charCodeAt(offset+0)); break; 
     case 0: return {b : b, c : c}; 
    } 

    o = Jenkins.final(a,b,c); 
    a = o.a; b = o.b; c = o.c; 

    return {b : b>>>0, c : c>>>0}; 
}  

}

+0

Hadi, eğlenceli olacak. Ayrıca, testler için geçerli bir veri kaynağınız varsa ...: p –

cevap

4

Kişisel bir proje için JavaScript'te Bloom filter uygulamak üzere bir JavaScript bağlantı noktası yaptığım lookup3.c. Yine de C koduyla aynı sonuçları üretip üretmediğinden emin değilim.

Doğrudan JavaScript'e dönüştürülmeyen ana şeylerden biri, anahtar girdisine işaretçi üzerinde gerçekleştirilen işaretçi aritmetiği'dur. Bunu nasıl ele aldığımı görmek için aşağıdaki kodda bulunan offset kelimesine bakın.

Tamsayı işaretsizymiş gibi bir çıktı isterseniz, returnValue >>> 0'u kullanabilirsiniz.

var BloomFilter = { 
    // Convert a JavaScript string into an array of 32-bit words. 
    // This preserves the UTF-16 encoding, padding with the null character if necessary. 
    stringToWords: function(s) { 
     var b = []; 
     if(s.length & 1) { 
      s += "\u0000"; 
     } 
     for (var i = 0; i < s.length; i += 2) { 
      b.push((s.charCodeAt(i) << 16) | (s.charCodeAt(i + 1))); 
     } 
     return b; 
    }, 

    // Hash an array of multiple 32-bit words to a single word. 
    // Adapted from "lookup3.c, by Bob Jenkins, May 2006, Public Domain." 
    // as retrieved 2010-07-03 from http://burtleburtle.net/bob/c/lookup3.c 

    hashWord: function(k, initval) { 
     // definition of bitwise rotate function 
     function rot(x, k) { 
      return (x << k) | (x >>> (32 - k)); 
     } 

     // initialization 
     var a, b, c, length = k.length, offset = 0; 
     a = b = c = (0xdeadbeef + (length << 2) + initval) | 0; 

     // handle most of the key 
     while(length > 3) { 
      a = (a + k[offset]) | 0; 
      b = (b + k[offset + 1]) | 0; 
      c = (c + k[offset + 2]) | 0; 

      // mixing function 
      a = (a - c) | 0; a ^= rot(c, 4); c = (c + b) | 0; 
      b = (b - a) | 0; b ^= rot(a, 6); a = (a + c) | 0; 
      c = (c - b) | 0; c ^= rot(b, 8); b = (b + a) | 0; 
      a = (a - c) | 0; a ^= rot(c,16); c = (c + b) | 0; 
      b = (b - a) | 0; b ^= rot(a,19); a = (a + c) | 0; 
      c = (c - b) | 0; c ^= rot(b, 4); b = (b + a) | 0; 

      length -= 3; 
      offset += 3; 
     } 

     // handle the final words if left over; fall-through is intended 
     switch(length) { 
      case 3: c = (c + k[offset + 2]) | 0; 
      case 2: b = (b + k[offset + 1]) | 0; 
      case 1: a = (a + k[offset]) | 0; 

      // final mixing 
      c ^= b; c = (c - rot(b,14)) | 0; 
      a ^= c; a = (a - rot(c,11)) | 0; 
      b ^= a; b = (b - rot(a,25)) | 0; 
      c ^= b; c = (c - rot(b,16)) | 0; 
      a ^= c; a = (a - rot(c, 4)) | 0; 
      b ^= a; b = (b - rot(a,14)) | 0; 
      c ^= b; c = (c - rot(b,24)) | 0; 

      case 0: break; // nothing left to do 
     } 

     // return the result 
     return c; 
    }, 

    // Hash a string by converting to UTF-16 before using the lookup3 algorithm. 
    hashString: function(s) { 
     return BloomFilter.hashWord(BloomFilter.stringToWords(s), 0); 
    } 
} 
+0

Lookup3.c'den farklı çıktılar elde ettiğine inanıyorum, ancak iki farklı sürümden daha hızlı _much_ oldukça yavaş (OP'ler dahil), ne yanlış gitti? – bryc

2

size hashlittle2 aynı karmaları verir değişiklikler, C code on Wikipedia, JavaScript'te mükemmel çalışacaktır. Sadece veri tiplerinden kurtulun ve uzunluğunu geçmek yerine key.length kullanın.

+0

Ama bu “My Hash” Jenkin'in hediyelerinden * farklı * (ve çok daha basit) bir karmaşadır: http: //www.burtleburtle. Diğer farklılıklar arasında bir karışım fazı içeren net/bob/hash/doobs.html. (Bire-bir-zaman-hash, söz konusu linkteki tartışma karmaşasından sadece biridir.) –

+0

@pst: Eh, bu sadece bir kaç vardiya ve diğer aritmetik işleçlerdir, bu yüzden çoğu JavaScript'te değişmeden çalışacaktır. . – casablanca

+0

@casablanca Sadece şunu belirtin :-) Ancak, taşmaların nasıl ele alınacağı konusunda fark olabileceğine inanıyorum - bu, JavaScript mantığına elle * eklenmelidir *. "Hash'um" işaretsiz bir 4 bayt varsayar ve 2'nin tamamlayıcısı olduğuna inanıyorum. –

İlgili konular