2016-07-17 16 views
-1

私はchar配列へのポインタを持っています。そして、各バイトを64ビットマスクでXORしてXORする必要があります。これを行う最も簡単な方法は、各8バイトを1つのlong longまたはuint64_tとXORで読み取ることだと思っていましたが、わかりません。たぶんlong long*にキャストして逆参照していますか?私はまだ一般的なポインタについてはまだ分かりませんので、どのようなサンプルコードも高く評価されます。ありがとう!C++のポインタからバイトシーケンスを読み込む方法は?

EDIT:サンプルコード(ちょうど私が欲しいものを示すために、私はそれが動作しません知っている):

void encrypt(char* in, uint64_t len, uint64_t key) { 
     for (int i = 0; i < (len>>3); i++) { 
      (uint64_t*)in ^= key; 
      in += 8; 
     } 
    } 
} 
+1

このルートを使用するには、char []が正しく配置されていることを確認する必要があります。性能が他に必要となるまで、一度に1バイトずつ作業するのが安全です。 – ildjarn

+0

あなたが達成したいものを正確に示すためには、少なくとも[minimal](http://stackoverflow.com/help/mcve)サンプルコードを追加してください。とにかくXORポインタバイトが必要なのはなぜですか? – Jezor

+0

@ildjarnこれを数メガバイトにしようとしているので、パフォーマンスが重要です。 :/ – TheAbelo2

答えて

3

あなたのXOR-マスキングを行うための簡単な方法は、バイトである:

void encrypt(uint8_t* in, size_t len, const uint8_t key[8]) 
{ 
    for (size_t i = 0; i < len; i++) { 
     in[i] ^= key[i % 8]; 
    } 
} 

注:keyは、64ビットではなく8バイトの配列です。このコードは簡単です。トリックは必要なく、簡単にデバッグすることができます。パフォーマンスを測定し、パフォーマンスが十分であればそれを使用します。

一部の(ほとんどの)コンパイラは、このような単純なコードをベクトル化によって最適化します。つまり、すべての詳細(キャストuint64_tなど)はコンパイラによって実行されます。ただし、コード内で "賢明"にしようとすると、誤ってコンパイラが最適化を実行できなくなる可能性があります。だから簡単なコードを書くようにしてください。

P.S.おそらく、restrictキーワードも使用してください。これは現在標準ではありませんが、最高のパフォーマンスを得るために必要な場合があります。私はそれを使用する経験がないので、私の例にそれを追加しませんでした。


あなたが悪いのコンパイラを持っている場合は、ベクトル化オプションを有効にするか、単に周りにプレイしたい、あなたは鋳造で、このバージョンを使用することができません。

void encrypt(uint8_t* in, size_t len, uint64_t key) 
{ 
    uint64_t* in64 = reinterpret_cast<uint64_t*>(in); 
    for (size_t i = 0; i < len/8; i++) { 
     in64[i] ^= key; 
    } 
} 

それはいくつかの制限があります。

  • 長さを8で割り切れるようにする必要があります
  • アライメントの合っていないポインタをサポートするプロセッサが必要です(x86についてはわかりません - おそらく動作します)
  • コンパイラが悪く、パフォーマンスにつながる、これをベクトル化することを拒否することがあり
  • Hurkylで述べたように、マスク内の8バイトの順序は、x86、リトルエンディアンに(明確ではないが、最下位バイトがマスクされます入力配列の最初のバイト)
+0

size_tとは何ですか?私は以前にそれに遭遇したことはありません。 – TheAbelo2

+0

size_tはサイズに適した型です。説明しています(http://en.cppreference.com/w/cpp/types/size_t) – anatolyg

+1

'std :: uint8_t'は、オブジェクト表現を読み込むための有効な型ではありません。これは' char '型、これはその許容量を持つ唯一のものなので、それを使用することは移植不可能であり、UBを危険にさらします。あなたの後半は非常に貧弱なアドバイスであり、UBの非常に効率的なジェネレータです。鋳造_from_ 'char *'は厳密なエイリアシングに違反しています(キャストの許容量との対称性はありません) –

関連する問題