他のデバイスにメッセージを送信する独自のプロトコルを備えた組み込みデバイスを使用しており、送信したパケットを解析するアプリケーションを作成しています。各パケットは8バイトを伝送します。プロトコルは、最初のバイトがヘッダーで、残りの7バイトがデータであると定義されています。
特定のID文字列を渡そうとしていますが、ID文字列は8文字(ASCII)なので、7バイトに収まりません。
同僚が私に言ったのは、元の文字列の8 ASCIIバイトを整数(10進数)に変換して、4バイトを送ってくれるということです。彼らは私に4バイトから元の文字列を取得できるはずだと言った。私はこれに頭を包むのに苦労しています。
つまり、「IO123456」のようなID文字列がある場合、それは0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36でASCIIです。いったいどうすれば整数に変換することで4バイトに圧縮でき、それから元の文字列を取得できます?何かが足りないのですか、それとも同僚が間違っているのですか?これは本当におかしな質問であることを理解していますが、これは私にはまったく意味がありません。
IDは常にIO123456の形式ですか?同僚が意味することは、彼は数値部分のみを送信するということです。これは、 "IO"部分を省略して4バイトに簡単に収まります。
最初の2文字が定数ではなく(常に文字)、残りの6文字が常に数値である場合、「IO123456」のような文字列は、数値を バイナリコードの10進数 に変換することで5バイトにパックできます。 =(BCD)形式:
IO123456 -> 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36
| | \ / \ / \ /
0x49 0x4f 0x12 0x34 0x56
可能な識別子のセットが限られている場合(最初の2文字)、これらを数値にエンコードし、代わりに(256の組み合わせを超えない限り)送信できます。例:
IO -> 0x00
RD -> 0x01
WT -> 0x02
...
AB -> 0x10
...
ZZ -> 0xff
情報を失うことなく、元の文字列が4バイトにパックされるようにします。
IO123456 -> 0x49 0x4f 0x31 0x32 0x33 0x34 0x35 0x36
\ / \ / \ / \ /
0x00 0x12 0x34 0x56
もちろん、このプロセスを逆にして元のID文字列を取得することもできます。
文字列が任意の文字シーケンスである場合:
文字列が各バイトの最上位ビットを使用していないことが確実な場合は、各ビットを7ビットにチョップし、ビットごとの演算を使用して残りの56ビットを使用可能な56ビットにシフトできます。
文字列が文字と数字のみの場合は、そのセットのみの6ビット表現を考え、識別子の48ビット文字列を作成します。
形式が常に2文字で、その後に数字列が続く場合:
最初の2バイトはそのままにして、数値を6バイト整数にエンコードします。 IO123456
は0x49 0x4f 0x01E240
になります。
最初の2バイトはそのままにして、数字を バイナリコード10進数 としてパックします。 IO123456
は0x49 0x4f 0x12 0x34 0x56
になります。
ここに投稿された質問の文脈から、それはHARTと呼ばれるいくつかの産業用プロトコルを指しています。このプロトコルには、ASCII文字をラップするユニークな方法があります。Packed-ASCIIと呼ばれます。ただし、8文字を4にパックしません!Packed-ASCIIによると、8 ASCIIバイトは6に変換されます。4から3に続きます。
このプロトコルでは、特定のリクエストのパラメータの長さは常に固定されています。したがって、残りの文字はスペース文字で埋める必要があります。それでも、これはHART固有のものです。これに取り組んでいることを確認したら、梱包と開梱の正確な手順を説明します。
おそらく「0123456」を長整数に変換することによって。
ただし、これは数値IDに対してのみ機能します。
別の可能なスキームは、6バイト文字列を提供する7ビットから6ビットのECMA-1エンコーディングに変換することですが、文字セットは数字の大文字と制限された句読文字のセットに制限されます。