2016-03-31 11 views
5

Aktualizacja:Konwersja Ilość STRING (Kodowanie Dostarczany) JavaScript

Poniższy kod działa doskonale aż $ char.to_text napotyka liczbą całkowitą większą niż 55,834,574,847.

alpha="abcdefghijklmnopqrstuvwxyz"; 
$char={ 
    to_num:function(s,c){ 
     var l=c.length,o={}; 
     c.split('').forEach(function(a,i){ 
      o[a]=i 
     }); 
     return s.split('').reduce(function(r,a){ 
      return r*l+o[a] 
     },0) 
    }, 
    to_text:function(i,c){ 
     var l=c.length,s=''; 
     do{ 
      s=c[i%l]+s; // i%l 
      i/=l; 
      i|=0 
     }while(i!==0); 
     return s 
    } 
}; 

Oto krótki wycinek:

$char.to_num("military",alpha) => 98987733674 
$char.to_text(98987733674,alpha) => "undefinedundefinedundefinedundefinedundefinedundefinedundefinedy" 

Ręcznie iteracji powyższy kod powinien generować normalną odpowiedź, dlaczego to wydajność tego „niezdefiniowanej ...” ciąg, jest to po prostu dlatego, że jest to duża liczba operacji dla JS?

+0

Wiesz, mogłeś po prostu stosować 'parseInt (a, 27)' ... – Bergi

+0

@Bergi, nie bardzo, co można uzyskać 1 ... 9, jak również. to wymagałoby pewnych zmian. –

+0

@NinaScholz: OK, po którym następuje 'replace' ... Ale biorąc pod uwagę, że w jego zestawie znaków znajduje się' 0', nie sądzę, aby liczba 1-9 miała znaczenie. – Bergi

Odpowiedz

2

Niniejszy wniosek o przepisanej hash funkcji, która używa obiektu o uproszczonych indexOf i prosty dla wartości pętli powrotnych.

Funkcja poszukiwana ihash używa pojedynczej pętli do ... until. Wykorzystuje resztę wartości i długość jako indeks podanego zestawu znaków. Wartość jest następnie dzielona przez długość zestawu znaków i część całkowita jest brana do następnej iteracji, jeśli nie równa zeru.

function hash(s) { 
 
    var c = '0abcdefghijklmnopqrstuvwxyz', 
 
     l = c.length, 
 
     o = {}; 
 

 
    c.split('').forEach(function (a, i) { 
 
     o[a] = i; 
 
    }); 
 
    return s.split('').reduce(function (r, a) { 
 
     return r * l + o[a]; 
 
    }, 0); 
 
} 
 

 
function ihash(i) { 
 
    var c = '0abcdefghijklmnopqrstuvwxyz', 
 
     l = c.length, 
 
     s = ''; 
 

 
    do { 
 
     s = c[i % l] + s; 
 
     i = Math.floor(i/l); 
 
    } while (i !== 0); 
 
    return s; 
 
} 
 

 
document.write(hash('0') + '<br>');   // => 0 
 
document.write(hash('a') + '<br>');   // => 1 
 
document.write(hash('hi') + '<br>');   // => 225 
 
document.write(hash('world') + '<br>');  // => 12531838 
 
document.write(hash('freecode') + '<br>'); // => 69810159857 
 

 
document.write(ihash(0) + '<br>');   // => '0' 
 
document.write(ihash(1) + '<br>');   // => 'a' 
 
document.write(ihash(225) + '<br>');   // => 'hi' 
 
document.write(ihash(12531838) + '<br>'); // => 'world' 
 
document.write(ihash(69810159857) + '<br>'); // => 'freecode'

+0

Ten fragment działa prawie idealnie; obawiam się jednak, że przestanie działać, jeśli liczba całkowita jest większa niż 55834574847. Nie mogę zrozumieć dlaczego, zakładam, że ma to związek ze środowiskiem liczbowym JS (nie jest szczególnie dobre w obsłudze dużych liczb/zmiennych). Publikowanie aktualizacji w celu wyświetlenia wyników – JoBro

+0

@JoBro, patrz edycja. Zmieniłem domyślny rzut na integer za pomocą 'Math.floor'. –

+0

Dziękuję bardzo! Działa to doskonale (: nadal jestem ciekawy, co zmieniło "i | = 0" na "i = Math.floor (i/l)" czy dokładnie? – JoBro

0

Oto pseudo kod do odzyskania łańcucha. Jest podobny do konwersji liczb różnych baz.

var txt = function(n, charset) { 
     var s ="" 
     while (n > 0) { 
      var r = n % charset.length; 
      n = n/charset.length; 
      s += charset[r]; 
     } 
     return s; 
    }