2016-05-05 3 views
0

私は以下のデコード/エンコードルーチンを持っています。ただし、エンコーディングが正しく機能していません(コンソールログに "ClaKA"ではなく "CMlaKA"が表示されます)。問題はビットシフトだと思うけど、どこに言えないの?ここでビットコードを使ったjavascriptのbase64エンコーディング

はここ

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

を説明するためのjsfiddleは、私はあなたの実装アルゴリズムを見つけましたが、これが見つかりませんでしたコード(ルーチンは一番下に実行される)

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

IE10よりも低いレベルをサポートしているのでない限り、ブラウザにbase64関数が既に存在する場合は、なぜ再作成するのですか? https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64 –

+0

ブラウザでJSを使用していません... –

答えて

0

です1つはwikipedia です。

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'は3つの' 8bit'文字から '24bit'です。 – GRiMe2D

+0

これは私が探している解決策ではないことに恐れています。最終結果は "CMlaKA"でなければなりません。この理由は、起こっているビットシフトのためです。私のバージョンは非常に近い "ClaKA"ですが、それでもまだ正しくはありません。あなたがビットシフトを動かすと(あなたの答えで行ったように)、base64エンコーディングは、同じである必要があるとき、完全に異なってくるでしょう。 –

0

あなたのコードにはいくつかの間違いがあり、encodeメソッドだけでなく、デコードも間違います。

まず、不正なキー文字列を使用しています。 Acciporing to Wikipedia Wikipedia - Base64 'A'は 'ではなく' 0 'です。あなたの例のように。

これにより、公開されているウェブサイトとのコードの正当性をチェックできなくなります。

このは、「標準」のキー文字列です:

_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/=", 

「=」の最後にパディングのためのものであり、

そして、変換時に直接使用すべきではない、あなたが得ましたあなたのバイトシフトコードに問題があります。 base64値を間違った方向に計算します。 Wikipediaのリンクを参照して、各バイトを各base64値と見なす必要があるかどうかを確認する必要があります。ここ

は、デコーダのために固定された抜粋である:ここ

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

は、エンコーダの固定断片である:

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

また、あなたが(エンコーダにおいて)出力値をトリミングしなければならないため

これらすべての変更を行ったと仮定すると、t彼のデコーダは "CMlaKA"で、出力は[12,217,155,44,16]であり、エンコーダは正しい答えを返します。

+0

こんにちは、彼らのキーストリング(私の理解)は、あなた自身の鍵でbase64を暗号化するためのパスワードを置くことができる場所です。上記の場合、実際に問題となる余分なドットがあります。エンコード/デコーディングは同じでなければなりません。 –

+0

@Ke。 'Base64' **は**暗号化ではありません。バイナリデータを* safe * ASCIIテキストに変換するだけです – GRiMe2D

+0

@ GRiMe2Dのように、Base64暗号化は悪い考えです!さらに、 '。'文字「A」のような標準値のインデックスがシフトされるので、検証のために値を「標準」デコーダ/エンコーダに比較しようとすると意味があります。 –

関連する問題