2011-09-07 19 views
1

チェックサムアルゴリズムで作業していますが、いくつか問題があります。私が受け取っている "実際の"データよりも実質的に小さい「偽の」メッセージを手に渡すと、キッカーは正しいチェックサムを取得します。しかし、実際のデータに対して、チェックサムは正しく機能しません。チェックサムアルゴリズムが予測不可能な結果を​​生成する

ここでは、着信データ/環境に関するいくつかの情報です:

  • これは、すべてのバイトは、チェックサム計算の目的のために、符号なし整数として扱われるべきであるグルーヴィープロジェクト(以下のコードを参照してください)
    • です
    • これを実現するには、短くて長いものがあります。
  • 実際のデータのサイズは491バイトです。
  • (正しく追加するために表示されます)私のサンプルデータのサイズは、私の進数と10進数の変換の26バイト
  • なし私は、ファイルに
  • いくつかのバイトを伝えることができる最善のように、負の数を、生産されていないですチェックサムに追加されません。私は、これらのスイッチが適切に動作していること、そしてそれが想定されていることを確認しました。それは問題ではありません。
  • 私の計算チェックサムと、実際の送信と一緒にパッケージ化されたチェックサムは、常に同じ量だけ異なります。
  • 実際のデータでパッケージ化されたチェックサムが正しいことを手動で確認しました。ここで

コードです:誰もが予想される結果からドリフトを引き起こしている可能性があり、このアルゴリズムで何かを見つけることができれば

// add bytes to checksum 
public void addToChecksum(byte[] bytes) { 
    //if the checksum isn't enabled, don't add 
    if(!checksumEnabled) { 
     return; 
    } 

    long previouschecksum = this.checksum; 

    for(int i = 0; i < bytes.length; i++) { 
     byte[] tmpBytes = new byte[2]; 
     tmpBytes[0] = 0x00; 
     tmpBytes[1] = bytes[i]; 

     ByteBuffer tmpBuf = ByteBuffer.wrap(tmpBytes); 

     long computedBytes = tmpBuf.getShort(); 
     logger.info(getHex(bytes[i]) + " = " + computedBytes); 
     this.checksum += computedBytes; 
    } 

    if(this.checksum < previouschecksum) { 
     logger.error("Checksum DECREASED: " + this.checksum); 
    } 
    //logger.info("Checksum: " + this.checksum); 
} 

、私は非常にこれを追跡するのにあなたの助けをいただければ幸いです。

+0

簡単な質問... md5、shaまたは他の証明されたハッシュアルゴリズムを使用してみませんか?つまり:http://groovyconsole.appspot.com/script/256001 –

+2

あなたの実装の詳細を知ることなく、CRC、MD5、SHAなどのよく知られた確立された十分なチェックサムアルゴリズムを使用しているのはなぜですか?理想に近い) –

+0

まず、どのチェックサムアルゴリズムが使用されているかを判断することはできません。だから、それは疑問な点です。私はプロトコルに準拠しなければなりません - それについてのオプションはありません。第二に、帯域幅を節約するために行われました。移動しているデータの量に応じて、このメソッドを使用すると実際のドル記号に変換されます。 –

答えて

0

this.checksumをリセットしたコードにコードが表示されません。

この方法では、いつもthis.checksum > previouschecksumを取得する必要がありますか?これは意図されていますか?

そうでないと上記のコードに欠陥が見つかりません。おそらくあなたの 'this.checksum'が間違ったタイプ(例えば、短い)であるかもしれません。これは、負の値を得るようにロールオーバーすることができます。ここ

はちょうど何とかご入力のな長さに対応して「数」変数の値で遊んで、そのような行動

import java.nio.ByteBuffer 
short checksum = 0 
byte[] bytes = new byte[491] 
def count = 260 
for (def i=0;i<count;i++) { 
    bytes[i]=255 
} 
bytes.each { b -> 
    byte[] tmpBytes = new byte[2]; 
    tmpBytes[0] = 0x00; 
    tmpBytes[1] = b; 
    ByteBuffer tmpBuf = ByteBuffer.wrap(tmpBytes); 
    long computedBytes = tmpBuf.getShort(); 
    checksum += computedBytes 
    println "${b} : ${computedBytes}" 
} 
println checksum +"!=" + 255*count 

ための一例です。

public void addToChecksum(byte[] bytes) { 
    //if the checksum isn't enabled, don't add 
    if(!checksumEnabled) { 
    return; 
    } 

    long previouschecksum = this.checksum; 
    this.checksum += bytes.inject(0L) { tot, it -> tot += it & 0xFF } 

    if(this.checksum < previouschecksum) { 
    logger.error("Checksum DECREASED: " + this.checksum); 
    } 
    //logger.info("Checksum: " + this.checksum); 
} 

しかし、それは停止しません:それは否定的であることにロールオーバーするまで(それは符号付きlong整数として)

+0

このメソッドは、より大きなクラスの一部にすぎません。そして、はい、「this.checksum」は常に「previouschecksum」よりも大きいべきです。私は負の数を生成している可能性を検出するためにその行を持っていました。それは厳密にはデバッグ戦術でした。また、「this.checksum」は長いです。 –

+0

491バイトが多すぎます。各反復の結果をすでに 'println'していますか? – rdmueller

+0

さて、491バイトはあまり聞こえないかもしれませんが、約80のコマンドになります。私は他の誰かが私の数学をチェックさせるために共有したいと思っていますが、それは独占的なものです。 : - \ –

0

あなたのチェックサムは、あなたがまたにあなたの方法を短縮することができますインクリメント

を維持しますそれは否定的に転覆する。あなたがハッシュを生成している項目ごとに12バイトを節約するために、私はまだ動作することを知っているMD5のようなものは、おそらく自分自身を圧延するよりも良いと示唆しています...しかし、私は時々あなたが守らなければならない狂気の要求があることを理解しています...

+0

幸いにも、私は合計が転がっている状況に遭遇していません。私が私の追加をするとき、それはちょうどそれがあるはずですが、それは信じられないほどイライラしています。 –

+0

また、短くしていただきありがとうございます! –

+0

@Matt見ているエラーの原因となるバイト配列の例がありますか? –

関連する問題