2016-05-05 15 views
0

Ich habe die folgende Dekodierung/Codierung Routine. Die Codierung funktioniert jedoch nicht ordnungsgemäß (es sollte "CMlaKA" und nicht "ClaKA" in das Konsolenprotokoll geschrieben werden). Ich denke, das Problem ist, dass sich das Bit verschiebt, aber ich kann nicht sagen, wo.Base64-Codierung in Javascript mit Bitverschiebung

ist hier ein jsfiddle

https://jsfiddle.net/4yfrLv9y/16/

Hier ist der Code zu erklären (Routine wird unten ausgeführt)

var consoleLine = "<p class=\"console-line\"></p>"; 

console = { 
    log: function (text) { 
     $("#console-log").append($(consoleLine).html(text)); 
    } 
}; 

var Base64 = { 
     _keyStr: ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=", 

    encode : function (input) { 
     var output = [], 
      chr1, chr2, chr3, enc1, enc2, enc3, enc4, 
      i = 0; 
     while (i < input.length) { 
      chr1 = input[i++]; 
      chr2 = input[i++]; 
      chr3 = input[i++]; 

      enc1 = chr1 & 0x3f; 
      enc2 = (chr1 >> 6) | ((chr2 & 0x3c) << 2); 
      enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 4); 
      enc4 = chr3 >> 2; 

      if (isNaN(chr2)) { 
       enc3 = enc4 = 64; 
      } else if (isNaN(chr3)) { 
       enc4 = 64; 
      } 

      output.push([this._keyStr.charAt(enc1), 
         this._keyStr.charAt(enc2), 
         this._keyStr.charAt(enc3), 
         this._keyStr.charAt(enc4)].join('')); 
     } 

     return output.join(''); 
    }, 

    decodeAsArray: function (b) { 
     var d = this.decode(b), 
      a = [], 
      c; 
       //alert("decoded base64:" + d); 
     for (c = 0; c < d.length; c++) { 
      a[c] = d.charCodeAt(c) 
     } 
       //alert("returning a"); 
     return a 
    }, 

    decode: function(input) { 
     var output = ""; 
     var chr1, chr2, chr3 = ""; 
     var enc1, enc2, enc3, enc4 = ""; 
     var i = 0; 

     do { 
      enc1 = this._keyStr.indexOf(input.charAt(i++)) ; 
      enc2 = this._keyStr.indexOf(input.charAt(i++)) ; 
      enc3 = this._keyStr.indexOf(input.charAt(i++)) ; 
      enc4 = this._keyStr.indexOf(input.charAt(i++)) ; 

      chr1 = (enc1 | ((enc2 & 3) << 6)); 
      chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4); 
      chr3 = (enc3 >> 4) | (enc4 << 2); 

      output = output + String.fromCharCode(chr1); 
      if (enc3 != 64) { 
       output = output + String.fromCharCode(chr2); 
         } 
      if (enc4 != 64) { 
       output = output + String.fromCharCode(chr3); 
      } 
      chr1 = chr2 = chr3 = ""; 
      enc1 = enc2 = enc3 = enc4 = ""; 
     } while (i < input.length); 

     return (output); 
    } 

}; 

basedecode(); 

function basedecode(){ 
//Converts 'CMlaKa to CcnK by base64' 
    var decoded = "CMlaKA" 
    //67 99 110 75 0 0 - This is the Byte Array, or ArrayBuffer of CcnK 
    decoded = Base64.decode(decoded) 
    console.log(decoded); 
} 

baseencode(); 

function baseencode(){ 
    var encoded = [67,99,110,75];// byte array of CcnK 
    console.log(Base64.encode(encoded) + ' ---- Should be CMlaKA not ClaKA== - why is it different?'); 
} 
+0

Wenn Sie nicht weniger als IE10 unterstützen, warum sollten Sie die base64-Funktionen neu schreiben, wenn sie bereits im Browser vorhanden sind? https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64 –

+0

Ich benutze JS nicht in einem Browser ... –

Antwort

0

ich Ihre Implementierung Algorithmus nicht gefunden konnte, fand aber diese eine in wikipedia und korrigierte Ihre

var consoleLine = "<p class=\"console-line\"></p>"; 

console = { 
    log: function (text) { 
     $("#console-log").append($(consoleLine).html(text)); 
    } 
}; 

var Base64 = { 
     _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/", 

    encode : function (input) { 
     var output = [], 
      chr1, chr2, chr3, enc1, enc2, enc3, enc4, 
      i = 0; 
     while (i < input.length) { 
      chr1 = input.charCodeAt(i); 
      chr2 = input.charCodeAt(i+1); 
      chr3 = input.charCodeAt(i+2); 
      i+=3; 

         /* enc1 = chr1 && 0x3f; 
         enc2 = (chr1 >> 6) | ((chr2 & 0x3c) << 4); 
         enc3 = (chr2 >> 4) | ((chr3 & 0x3) << 2); 
         enc4 = chr3 >> 2; */ 

      var _24c = (chr1 << 16) + (chr2 << 8) + chr3; 
      //n = [(n >>> 18) & 63, (n >>> 12) & 63, (n >>> 6) & 63, n & 63]; 
      enc1 = _24c >>> 18 & 63 
      enc2 = _24c >>> 12 & 63 
      enc3 = _24c >>> 6 & 63 
      enc4 = _24c & 63 


      /** if (isNaN(chr2)) { 
       enc3 = enc4 = 64; 
      } else if (isNaN(chr3)) { 
       enc4 = 64; 
      } 
      */ 
      output.push([this._keyStr.charAt(enc1), 
         this._keyStr.charAt(enc2), 
         this._keyStr.charAt(enc3), 
         this._keyStr.charAt(enc4)].join('')); 
     } 

     return output.join(''); 
    }, 

    decodeAsArray: function (b) { 
     var d = this.decode(b), 
      a = [], 
      c; 
       //alert("decoded base64:" + d); 
     for (c = 0; c < d.length; c++) { 
      a[c] = d.charCodeAt(c) 
     } 
       //alert("returning a"); 
     return a 
    }, 

    decode: function(input) { 
     var output = ""; 
     var chr1, chr2, chr3 = ""; 
     var enc1, enc2, enc3, enc4 = ""; 
     var i = 0; 

     do { 
      enc1 = this._keyStr.indexOf(input.charAt(i++)) ; 
      enc2 = this._keyStr.indexOf(input.charAt(i++)) ; 
      enc3 = this._keyStr.indexOf(input.charAt(i++)) ; 
      enc4 = this._keyStr.indexOf(input.charAt(i++)) ; 

      chr1 = (enc1 | ((enc2 & 3) << 6)); 
      chr2 = (enc2 >> 2) | ((enc3 & 0x0F) << 4); 
      chr3 = (enc3 >> 4) | (enc4 << 2); 

      output = output + String.fromCharCode(chr1); 
      if (enc3 != 64) { 
       output = output + String.fromCharCode(chr2); 
         } 
      if (enc4 != 64) { 
       output = output + String.fromCharCode(chr3); 
      } 
      chr1 = chr2 = chr3 = ""; 
      enc1 = enc2 = enc3 = enc4 = ""; 
     } while (i < input.length); 

     return (output); 
    } 

}; 

// basedecode(); 

function basedecode(){ 
//Converts 'CMlaKa to CcnK by base64' 
    var decoded = "CMlaKA" 
    //67 99 110 75 0 0 - This is the Byte Array, or ArrayBuffer of CcnK 
    decoded = Base64.decode(decoded) 
    console.log(decoded); 
} 

// baseencode(); 

function baseencode(){ 
    var encoded = [67,99,110,75];// byte array of CcnK 
    console.log(Base64.encode(encoded) + ' ---- Should be CMlaKA not +la+A== - where do the + and = signs come from?'); 
} 

function hashAndAssert(string_to_hash, result) { 
    var hash = Base64.encode(string_to_hash); 
    return '' + (hash == result) + ', expected: ' + result + '; output: ' + hash; 
} 

function unitTest() { 
    console.log('#1 Passed ' + hashAndAssert('', '')) 
    console.log('#2 Passed ' + hashAndAssert('foo', 'Zm9v')) 
    console.log('#1 Passed ' + hashAndAssert('foobar', 'Zm9vYmFy')) 
} 

unitTest(); 
+1

'_24c' ist ein' 24bit' Zeichen von 3 '8bit' Zeichen . – GRiMe2D

+0

Ich fürchte, das ist nicht die Lösung, die ich suche. Das Endergebnis sollte "CMlaKA" sein. Der Grund dafür liegt in der Bitverschiebung, die passiert. Meine Version ist sehr nah "ClaKA", aber es ist immer noch nicht ganz richtig. Wenn Sie das Bit verschieben (wie Sie es in Ihrer Antwort getan haben), wird die base64-Kodierung völlig anders aussehen, wenn sie gleich sein muss. –

0

Es gibt ein paar Fehler in Ihrem Code und sie beinhalten nicht nur die Encode-Methode, sondern auch die Decodierung.

Zuerst verwenden Sie eine ungültige Schlüsselzeichenfolge. Gemäß Wikipedia Wikipedia - Base64 'A' entspricht '0', nicht '.' wie in deinem Beispiel.

Dies verhindert, dass Sie Ihren Code auf öffentlichen Websites auf Gültigkeit überprüfen.

Dies ist der "Standard" key string:

_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/=", 

Die '=' am Ende für Polsterung und nicht direkt bei der Konvertierung

Dann bekam verwendet werden, sollten Sie sich ein Problem mit Ihrem Byte-Shifting-Code. Sie berechnen die Base64-Werte in die falsche Richtung. Sie sollten sich den Wikipedia-Link ansehen, um zu sehen, welche Bytes als base64-Wert betrachtet werden sollten.

Hier ist ein fester Schnipsel für den Decoder:

chr1 = enc1 << 2 | ((enc2 & 0xc0) >> 6); 
chr2 = ((enc2 & 0x0f) << 4) | ((enc3 & 0x3c) >> 2); 
chr3 = ((enc3 & 0x03) << 6) | enc4; 

Hier ist ein fester Schnipsel für den Encoder:

enc1 = (chr1 & 0xfc) >> 2; 
enc2 = ((chr1 & 0x03) << 4) | ((chr2 & 0xf0) >> 4); 
enc3 = ((chr2 & 0x0f) << 2) | ((chr3 & 0xc0) >> 6); 
enc4 = chr3 & 0x3f; 

Darüber hinaus müssen Sie die Ausgangswerte trimmen (im Codierer), weil sie sind in unbegrenzten Containern, also:

Angenommen, Sie alle diese Änderungen vorgenommen, wenn die Eingabe zu t Der Decoder ist "CMlaKA", der Ausgang ist [12,217,155,44,16] und dann gibt der Encoder die richtige Antwort zurück.

+0

Hallo, sie Schlüssel-String (mein Verständnis davon) ist, wo Sie ein Passwort eingeben können, um die Base64 mit Ihrem eigenen Schlüssel zu verschlüsseln. Im obigen Fall gibt es nur einen zusätzlichen Punkt, der nicht wirklich wichtig ist. Die Kodierung/Dekodierung sollte gleich sein. –

+0

@Ke. 'Base64' ** verschlüsselt nicht **. Es konvertiert nur binäre Daten in * sicheren * ASCII-Text – GRiMe2D

+0

Genau wie @ GRiMe2D sagte, Base64-Verschlüsselung ist eine schlechte Idee! Außerdem ist das "." ist signifikant, wenn Sie versuchen, die Werte mit einem "Standard" -Decoder/-Codierer zur Verifizierung zu vergleichen, da die Indizes der Standardwerte, wie der Buchstabe "A", verschoben sind. –