0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【COBS】:感動のデータエンコーディング革命!奇跡の効率アップ&サイズ削減で心揺さぶられる未来への扉を開く

Posted at

最初に

わけわからんタイトルですが文句はChatGPT君に。
(COBS自体は1999年のInternet Draftで提案されているので革命でもなんでもないです。昔からあります。)

研究を進める中で出てきたことをまとめました。

概要

シンプルなデータのエンコード方式としてはSLIP(Serial Line Internet Protocol)というものがあります。
しかし、SLIPは最悪の場合、元データの二倍の大きさになるという問題があります。

そこで、COBS(Consistent Overhead Byte Stuffing)という手法を頭のいい人が考案。
最大パケットが255byteの条件下では、最悪でも元データ+5に収めることを可能にしました。

本題

SLIP

では、もう少し細かい話をしていきます。

データが連続して送られてくる状況では、どこからどこまでがパケットか分からなくなります。
(0101011011101から必要なデータはこれとこれ、なんてわからないですよね)

そこで、特定の文字(デリミタ)を目印にする「SLIP」というシンプルな方法が考案されました。
データ中にデリミタ0xFFで挟まれた部分をパケットとして認識するという感じです。

SLIPはデータ中にデリミタが出現した場合、ほかの文字に置換します。(例 0xFF -> 0x01FD)
1byteのデリミタを2byteで置き換えるので、全てがデリミタと同じ値のデータではサイズが2倍になってしまいます。

COBS

エンコード

COBSはこの課題をクリアしたエンコード方式です。
ざっくりと言うと、デリミタの出現を置換で表現したSLIPに対し、ブロックの長さで表現したのがCOBSです。

COBSでは1パケットを複数のブロックに分けます。
また、MBS(Max Block Size)を定義しておきます。

具体的なエンコード方式は以下のようになります。

  1. 元データに末尾にデリミタを追加
  2. 元データを先頭からサーチします。
    ・デリミタが出現した
    ・連続してMBS分、読み込んだ
    上の2パターンの内、どちらかを満たした場合ブロックを確定
  3. ・デリミタが出現したブロックはデリミタを削除。
    ・MBS読み込んだブロックはなにもしない
  4. 各ブロックの長さを表すデータをブロックの先頭に挿入。これをOHB(OverHead Byte)といいます
  5. 以下2~4を元データ末尾まで繰り返す
    スクリーンショット 2023-05-25 125208.png

デコード

デコードの場合はOHBを読み込み、各OHB分のブロックを切り取ります。

ここでOHBがMBS未満ならば、デリミタが出現したデータとみなしてブロックの末尾にデリミタを追加します。
もし、MBSの場合はデリミタ未出現として操作はしません。
この操作をOHB後のデータがデリミタを指すまで繰り返します。

##Pythonによる実装


def blockize_data(data, delimiter, mbs):
    blocks = []
    block = ''
    delimiter_found = False

    # Step 1: Append delimiter to the end of the data
    data += delimiter

    # Step 2 and 3: Search for delimiter or consecutive non-delimiter characters
    for char in data:
        if char == delimiter:
            if block:
                blocks.append(block)
                block = ''
            delimiter_found = True
        elif delimiter_found or len(block) == mbs:
            blocks.append(block)
            block = char
            delimiter_found = False
        else:
            block += char

    # Step 4: Output blocks
    for block in blocks:
        if block.endswith(delimiter):
            block_size = len(block) - 1
            block = block[:-1]
        else:
            block_size = len(block)
        print(f"OH: {block_size}")
        print(block)

    # Step 5: Append delimiter to the end
    print(f"OH: 0")
    print(delimiter)

参考文献

Consistent Overhead Byte Stuffing

最後に

記事の誤り等がありましたら、教えていただけたら幸いです。

大学では衛星の開発と衛星データの処理をやってます。
中々大変です

学生じゃないみたいだなぁ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?