2016-11-04 16 views
1

私はHTTP GETで与えられたデータをデコードしようとしています。基本的にはPythonでエンコードされていて、Nodeを使ってデコードしようとしています。Python urllib.unquote_plus node.js相当の

Pythonの

data = "0%0E%09-%FB%CD%989%2B%C0%E5%A2+%28%93%D9%C9%86r0%9C%8D+%F1%E3v%0C%9E%19%91%E3%06%01%FA%D5%5B%F3%3D7%10%23%E7%95S%B7%93%60%DB%1F%1F%8A%E3%5D%CC%95%B8%DA%DB%A3%18%9FoVzC%23%FCB%8D%86%86N9%BE%AE%98%13x%0D%D9u%C48%F6%AD%A3%19z%BE%DB%8E-%C4T%02P%06%D5%C1%21%1F%FB%9C%EB%0A%7C%F9XFB%9D%F3" 
print urllib.unquote_plus(data) 

出力:

0 -�͘9+�� (��Ɇr0�� ��v 
�u�8�z�ێ-�TP��!��   �����[�=7#�S��`���]̕��ۣ�oVzC#�B���N9���x 
|�XFB�� 

ノード

var token = '0%0E%09-%FB%CD%989%2B%C0%E5%A2+%28%93%D9%C9%86r0%9C%8D+%F1%E3v%0C%9E%19%91%E3%06%01%FA%D5%5B%F3%3D7%10%23%E7%95S%B7%93%60%DB%1F%1F%8A%E3%5D%CC%95%B8%DA%DB%A3%18%9FoVzC%23%FCB%8D%86%86N9%BE%AE%98%13x%0D%D9u%C48%F6%AD%A3%19z%BE%DB%8E-%C4T%02P%06%D5%C1%21%1F%FB%9C%EB%0A%7C%F9XFB%9D%F3'; 
console.log(unescape(_.replace(token, '+', '%20'))) 

_ is Lodash library. See https://lodash.com/docs/4.16.6#replace

出力:

0 -ûÍ9+Àå¢ (ÙÉr0+ñãv 
ÙuÄ8ö­£z¾Û-ÄTPÕÁ!ûë   ãúÕ[ó=7#çS·`Ûã]̸ÚÛ£oVzC#üBN9¾®x 
|ùXFBó 

2つのデコード出力は似ていますが、まだ少し異なっていて、私は理由を理解することはできません。一度解読すると(別のアルゴリズムで)同様の結果が得られますが、JSバージョンには予期しない文字({"duration": 600m�B�}PO�UQ��:...}'など)があり、JSの実装に間違いがないかどうかはわかりません。

+0

Pythonのデータはすでに壊れて見えます。それは何を表わすはずですか? Theは、文字セットの復号化エラーを示します。したがって、望ましい結果になることはほとんどありません。また、JS 'unescape()'関数は何年にもわたって廃止されました。何にも使わないでください。 – Tomalak

+0

パディングを使用してAES 256 CBCを使用して暗号化された文字列なので、壊れているようです。しかし、結果はバイナリデータであり、 'quote_plus'を使ってコード化されているので、(私が理解する限り)それだけです。この文字列をPythonでデコードして解読すると、うまく動作します。しかしデコードされた価値は本当に変わっています。 – Vadorequest

+0

ああ、そうだ。文字列としてデコードされた任意のバイナリ値は、そのように見えます。 – Tomalak

答えて

1

これが以前に行われたかどうかはわかりません(おそらく、私が正しく検索しなかった可能性があります)。

通常のURLデコード機能がしようとするように、パーセントエンコードの文字列を文字列ではなくバイトのバッファにデコードする関数が必要です。

function bufferUrlDecode(data) { 
    var buf = new Buffer(data, 'ascii'); 
    var pos = 0, flag = false, prev = null, i, b; 

    for (i = 0; i < buf.length; i++) { 
     b = buf[i]; 
     if (flag) { 
      b -= b < 58 ? 48 : b < 97 ? 55 : 87; // hex char to half-byte value 
      if (b < 0 || b > 15) { 
       throw new Error('invalid encoding at position ' + i); 
      } else if (prev === null) { 
       prev = b << 4; 
      } else { 
       buf[pos++] = prev + b; 
       flag = false; 
       prev = null; 
      } 
     } else { 
      if (b === 43 /* '+' becomes space */) { 
       buf[pos++] = 32; 
      } else if (b === 37 /* '%' triggers URL decoding */) { 
       flag = true; 
      } else { 
       buf[pos++] = b; 
      } 
     } 
    } 

    if (prev !== null) throw new Error('invalid encoding at position ' + data.length); 
    return buf.slice(0, pos); 
} 

用法:

var str = "0%0E%09-%FB%CD%989%2B%C0%E5%A2+%28%93%D9%C9%86r0%9C%8D+%F1%E3v%0C%9E%19%91%E3%06%01%FA%D5%5B%F3%3D7%10%23%E7%95S%B7%93%60%DB%1F%1F%8A%E3%5D%CC%95%B8%DA%DB%A3%18%9FoVzC%23%FCB%8D%86%86N9%BE%AE%98%13x%0D%D9u%C48%F6%AD%A3%19z%BE%DB%8E-%C4T%02P%06%D5%C1%21%1F%FB%9C%EB%0A%7C%F9XFB%9D%F3";  
var bytes = bufferUrlDecode(str); 
console.log(bytes); 
console.log(bytes.toString('hex')); 

出力:

<Buffer 30 0e 09 2d fb cd 98 39 2b c0 e5 a2 20 28 ... > 
300e092dfbcd98392bc0e5a22028 etc... 
+0

デコードAES-256-CBCアルゴリズム(文字列としても)でバッファを使用できないため、これは私の使用例ではうまくいかないと思います。私は現在、 'エラー:エラー:0606506D:デジタルエンベロープルーチン:EVP_DecryptFinal_ex:間違った最終ブロック長'を試してみます。私が探しているのは、ノードに 'urrllib.unquote_plus'が正しく実装されていることです。私は 'unescape'と' replace'を混ぜてみましたが、何かが欠けています。 – Vadorequest

+0

Hm。'crypto'モジュールの中のメソッドはバッファで動作するので、"バッファは使えません "ということをどういう意味か分かりません。私の実装には愚かな間違いがありました。再試行する。 – Tomalak

+0

@ Vadorequest私の機能は正しい出力を提供します。あなたに与えることができるフィードバックはありませんか? – Tomalak