2009-06-10 11 views
3

私は接続されたデバイスからデータを読み込むためにpySerialを使用しています。私は各受信パケットのチェックサムを計算したい。パケットはchar配列として読み込まれ、実際のチェックサムはパケットの最後の最後のバイトです。チェックサムを計算するには、通常、パケットのペイロードを合計し、それを実際のチェックサムと比較します。Pythonでオーバーフローで2バイトを追加する方法はありますか?

通常、Cのような言語では、チェックサム自体が1バイトであるため、オーバーフローが予想されます。私はPythonの内部については分かりませんが、言語に関する私の経験から、より大きなサイズの変数(おそらく内部bigIntクラスなど)がデフォルトになるように見えます。とにかく、私自身の実装を書かずに、2つの文字を追加すると予想される動作を模倣することはありますか?ありがとう。

答えて

6

確かに、結果のモジュラスを取って、希望のサイズに戻してください。モジュラスは、最後またはすべてのステップで行うことができます。例:

>>> payload = [100, 101, 102, 103, 104] # arbitrary sequence of bytes 
>>> sum(payload) % 256 # modulo 256 to make the answer fit in a single byte 
254 # this would be your checksum 
+3

ニースの簡単な例。バイトに切り捨てるもう1つの一般的な方法は、0xFFのビット単位のANDであるため、 "sum(payload)&0xFF"です。 –

+0

@benhoytは私たちが同じことを考えているように見えます;-) – nategood

2

前述の例では改善のために、ビットごとに0xFFを使用しています。 Pythonがデフォルトで最適化を行うかどうかはわかりません。

sum(bytes) & 0xFF 
+0

Pythonが何をしているのかよく分かりませんが、クイックテストではどちらのメソッドもほとんど同じ時間がかかることがわかります。いずれにせよ、集計は仕事の大部分を占めるだろう。 – Kiv

+0

ほとんどの最適化コンパイラは強度低下を行い、 "%(2^n)"を "&((1 << n)-1)"として実装します。 Pythonインタプリタが同じことをするのはあまり難しくありません。 –

+0

"dis.dis(lambda x:x%256)"の出力を見ると、この最適化が適用されていないように見えます。ランタイムのわずかな違いは、おそらく、実際の/ mod操作が総コストのごく一部であるという事実によるものです。 – Brian

0

バイトを加算した後sum(bytes) % 256(又はsum(bytes) & 0xFF)のように、弾性率を取る整数タイプが表すことができる有限の最大値が存在するので、(多くのプログラミング言語で)オーバーフローを整数に脆弱です。

しかし、私たちはPythonについて話しているので、これは技術的に問題ではありません。Pythonの整数は任意精度であるため、整数のオーバーフローは発生しません。

あなたは要素ごとに剰余演算を実行する場合、あなたはfunctools.reduce()を使用することができます。

>>> payload = [100, 101, 102, 103, 104] # arbitrary sequence of bytes 
# (Python 3 uses functools.reduce() instead of builtin reduce() function) 
>>> import functools 
>>> functools.reduce(lambda x,y: (x+y)%256, payload) 
254