0

わかりました。生のSHA1ハッシュを使用して、メルセンヌツイスターの疑似乱数ジェネレーターをシードしています。ジェネレーターには、unsignedlongまたはunsignedlongの配列のいずれかをシードするオプションがあります。

私が使用しているSHA1クラスは、ハッシュをunsignedcharsの20バイト配列として提供します

このcharの配列をlongの配列に再キャストして、機能するシードを取得できると思いましたが、結果のlongの配列の長さをどのように知ることができますか?

サンプルコード:

CSHA1 sha1;
sha1.Update((unsigned char*)key, size_key);
sha1.Final();
unsigned char* hash;
sha1.GetHash(hash);

// Seed the random with the key
MTRand mt((unsigned long*)hash, <size of array of longs>);

暗号化の安全性を維持するためにこれが必要なので、データの損失がないことを望んでいます(バイトがドロップオフされないため)。

4

3 に答える 3

1

len_of_chars * sizeof(char) / sizeof(long)を使用できますlen_of_chars。おそらく20です。

于 2012-10-23T01:47:54.437 に答える
1

あなたは言うことができます

sizeof(unsigned long) / sizeof(unsigned char)

長いオクテットの数を取得します。

ただし、単純なキャストには2つの潜在的な問題があります。

まず、charの配列が適切に整列されていない可能性があります。一部のプロセッサでは、これによりトラップが発生する可能性があります。他の人では、実行が遅くなるだけです。

次に、プログラムが異なるアーキテクチャで同じように動作する必要がある場合は、バイト順序の問題を求めています。

バイトをlongの配列に明示的にコピーすることで、両方の問題を解決できます。テストされていないコード:

const int bytes_per_long = sizeof(unsigned long) / sizeof(unsigned char);
unsigned long hash_copy[key_length_in_bytes / bytes_per_long];
int i_hash = 0;
for (int i_copy = 0; i_copy < sizeof hash_copy / sizeof hash_copy[0]; i_copy++) {
  unsigned long b = 0;
  for (int i_byte = 0; i_byte < bytes_per_long; i_byte++)
    b = (b << 8) | hash[i_hash++];
  hash_copy[i_copy] = b;
}
// Now use hash_copy.
于 2012-10-23T02:00:34.423 に答える
0

あなたのライブラリは32ビットを想定しているようですunsigned longので、同じことをしても害はありません。実際、私は8ビットを想定しunsigned char、おそらく両方にパディングされていないリトルエンディアンの表現を想定しています。したがって、単純なキャスト(私はを使用しますがreinterpret_cast)を使用することも、@Geneのmemcpyサンプルを使用して位置合わせすることもできます。

ただし、ポータブルコード*では、変換にその中<cstdint>uint#_tタイプと区分的値によるコピーを使用する必要があります。

uint32_t littleEndianInt8sToInt32(uint8_t bytes[4]) {
    return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
}

...そしてより良い名前。申し訳ありませんが、ここで遅くなっています:)

*:もちろん、stdint それ自体はあまり移植性がなく(> = C ++ 11)、正確な幅のタイプが含まれるとは限りません。皮肉な。

于 2012-10-23T02:33:55.623 に答える