2017-04-15 4 views
0

私はCRC計算でそれを使用するために、文字の配列をuint32_tの配列に変換しようとしています。これを行う正しい方法であるか、それとも危険なのか不思議でしたか?私は危険な変換を行う習慣があり、危険性の低いものを変換するより良い方法を学ぼうとしています:)。私は配列の各文字が8ビットであることを知っています。私は4つの文字を合計し、それをunsigned int配列のインデックスに投げるべきですか、それとも別の配列に各文字を配置するだけでいいですか? 4つの8ビット文字を合計すると、その値が配列に変更されますか?私は文字のシフトについて何かを読んだことがありますが、4つの文字をunsigned int配列の1つのインデックスにシフトする方法は正確にはわかりません。文字の配列をcintのuint32_tの配列に変換するのは適切ですか?

text [i]は文字の配列です。

uint32_t inputText[512]; 
for(i = 0; i < 504; i++) 
{ 
    inputText[i] = (uint32_t)text[i]; 
} 

答えて

1

キャストは正常です。あなたがuint32_tの配列が512であるときにi < 504と言う理由がわかりません(504値のみを変換し、512の長さの配列が必要な場合は、array[512] = {0}を使用してメモリを確保することができます)。それにもかかわらず、これは完全に安全であると言うことができます:SomeArrayOfLargerType[i] = (largerType_t)SomeArrayOfSmallerType[i]しかし、今のところ、バイナリは次のようになります:

0100 0001 -> 0000 0000 0000 0000 0000 0000 0100 0001 

したがって、0を先導するものは望ましくない結果になる可能性があります。

4つの文字を合計すると、ほとんど間違いなくあなたが望むようにうまくいかないでしょう。あなたが文字通り0000 0001(1)+ 0000 0010(2)= 0000 0100(3)のような合計をほしいと思わない限り、前の例で00000001 000000010を生成する場合は、シフトを適用する必要があります。

UPDATEから例を経由してシフトに関するいくつかの情報を:

次は、シフトの例のようになります。

uint32_t valueArray[FINAL_LENGTH] = {0}; 
int i; 
for(i=0; i < TEXT_LENGTH; i++){ // text_length is the initial message/text length (512 bytes or something) 
    int mode = i % 4; // 4-to-1 value storage ratio (4 uint8s being stored as 1 uint32) 
    int writeLocation = (int)(i/4); // values will be truncated, so something like 3/4 = 0 (which is desired) 
    switch(mode){ 
     case(0): 
      // add to bottom 8-bits of index 
      valueArray[writeLocation] = text[i]; 
      break; 
     case(1): 
      valueArray[writeLocation] |= (text[i] << 8); // shift to left by 8 bits to insert to second byte 
      break; 
     case(2): 
      valueArray[writeLocation] |= (text[i] << 16); // shift to left by 16 bits to insert to third byte 
      break; 
     case(3): 
      valueArray[writeLocation] |= (text[i] << 24); // shift to left by 24 bits to insert to fourth byte 
      break; 
     default: 
      printf("Some error occurred here... If source has been modified, please check to make sure the number of case handlers == the possible values for mode.\n"); 
    } 
} 

あなたはここでその実行の例を見ることができます:https://ideone.com/OcDMoMを(IDEOneで実行すると実行時エラーが発生することに注意してください。出力はまだ正確でコードは単なる例として役立つので、私はその問題を強く見ていません。

基本的に、各バイトは8ビットであり、バイトを4バイトチャンク(それぞれ32ビット)で保存する必要があるため、シフトする方法は4通りあります。最初のケースでは、最初の8ビットがメッセージの1バイトで埋められます。第2の場合、第2の8ビットはメッセージ内の次のバイトで埋められる(は8ビットだけシフトされているので、これは2進位置のオフセットであるため)。そして、それは残りの2バイトのために続き、そしてそれは最初のメッセージ配列の次のインデックスから始まって繰り返されます。

バイトを結合するとき、|=が使用されます。これは、すでにuint32にあるものを取り、ビット単位のORを実行するため、最終的な値が1つの単一値に結合されるためです。

だから、私は私の最初の記事で持っていたもののような単純な例を打破するために、のは、私は彼らに0000 0000 0000 0000を保持するために、最初の16ビット整数で、0000 0001(1)と0000 0010(2)を持っているとしましょう。最初のバイトは、それを0000 0000 0000 0001にする16ビット整数に割り当てられます。その後、2番目のバイトは8だけ左にシフトされ、0000 0010 0000 0000になります。最後に、2つはビット単位のORを使用しているため、16ビット整数は0000 0010 0000 0001になります。

4バイトを保持する32ビット整数の場合、そのプロセスは8回の追加シフトでさらに2回繰り返され、次のuint32に進みプロセスを繰り返します。

うまくいけば、それは意味をなさないでしょう。もしそうでなければ、私はさらに明確にしようとすることができます。

+0

私は明らかに教師の答えと一致するCRCを得るためにシフトを使う必要があります。彼は私に、4つの16ビットチャンクを使用して64ビットラインごとのCRCを計算しようと言った。しかし、unsigned intは32ビットである必要があります。私は、チャンクを作成するために32ビットにするために文字を配列にシフトする必要があると仮定しています。また、将来のためには良い知識があるように感じます。私に助けてもらえますか? – starlight

+0

@starlight、個人的には、私はCRCチェックサムの実装を調べたことがないので、それがどのように機能するかについて正確な答えを与えることはできません(コースに参加することの全体的なポイントは、それらのことを独立して行う)。しかし、私はそれをどうやって変えることができるのかという一般的な例をお伝えします。ちょうど答えを更新するために私に数分を与える。 – SpencerD

+0

ありがとう、私はそこから行くことができるはずです! :) – starlight

関連する問題