0

XOR で文字列を暗号化する次の C++ コードがあります。

#define MPI_CIPHER_KEY "qwerty"

Buffer FooClient::cipher_string(const Buffer& _landing_url)
{
    String key(CIPHER_KEY);
    Buffer key_buf(key.chars(), key.length());
    Buffer landing_url_cipher = FooClient::XOR(_url, key_buf);

    Buffer b64_url_cipher;
    base64_encode(landing_url_cipher, b64_url_cipher);

    return b64_url_cipher;
}

Buffer FooClient::XOR(const Buffer& _data, const Buffer& _key)
{
    Buffer retval(_data);
    unsigned int klen=_key.length();
    unsigned int dlen=_data.length();
    unsigned int k=0;
    unsigned int d=0;

    for(;d<dlen;d++)
    {
        retval[d]=_data[d]^_key[k];
        k=(++k<klen?k:0);
    }

    return retval;
}

この質問で、そのような Java implを見てきました。それはこのケースでうまくいくでしょうか?

String s1, s2;

StringBuilder sb = new StringBuilder();
for(int i=0; i<s1.length() && i<s2.length();i++)
    sb.append((char)(s1.charAt(i) ^ s2.charAt(i)));
String result = sb.toString();

またはそれを行う簡単な方法はありますか?

4

2 に答える 2

3

私には同じに見えません。C++ バージョンは、_key の長さに関係なく、すべての _data にわたってループし、必要に応じて _key を循環します。( k=(++k<klen?k:0);C++ コード内)

あなたのものは、最短のキーまたはデータがヒットするとすぐに返されます。

個人的には、C++ から Java への最も近いリテラル変換から始めて、param とローカル名を同じに保ちます。

次に、C++ からの既知の入力と出力を持つユニット テストを記述します。

次に、Java バージョンを Java イディオム/etc を使用するようにリファクタリングし始め、テストが確実にパスするようにします。

于 2012-10-02T18:04:43.177 に答える
1

いいえ - Java コードは小さい文字列の長さまでのみ XOR を実行しますが、C++ コードはデータ全体を完全に XOR します。s1 が「キー」であると仮定すると、これは次のように変更することで修正できます

for(int i=0; i<s2.length();i++)
     sb.append((char)(s1.charAt(i%s1.length()) ^ s2.charAt(i)));

また、戻り値の base-64 エンコーディングが欠落しています。

于 2012-10-02T18:03:19.390 に答える