質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2511閲覧

jsonをCBORに変換したい

pokemonta

総合スコア170

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

3クリップ

投稿2020/03/24 15:51

以下のサイトを参考にpythonで自動変換を実施したいです。
方法をご教示頂けないでしょうか

どうゆう法則性で変換するのか?
なぜサイズが違うのかが全然わかりません

Value    CBOR JSON
0       1   1
23       1   2
[1, 2, 3, 4] 5   9

リンク内容

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ValueCBOR (バイト列)CBOR lenJSON (文字列)JSON len
0\x001"0"1
23\x171"23"2
[1,2,3,4]\x84 \x01 \x02 \x03 \x045"[1,2,3,4]"9

こういうことでしょうか。

なぜサイズが違うのかが全然わかりません

「バイト」単位でデータを見ても解り難いですが、「ビット」単位だと未使用領域が有り
一般的にバイナリフォーマットでは、ビット単位でメモリを効率良く使うことで省サイズを実現します。

全部説明するとなると膨大な量になるので、
例に挙げられた値のみに絞って説明します。

  • 0..23迄の整数
  • 0..23迄の長さの配列

0..23 の範囲の整数

  • JSONでは、数値の桁数=サイズ
  • CBORでは変換なし。サイズは常に1

python

1def cbor_encode_number(num): 2 if 24 > num >= 0: # 0..23の範囲 3 return bytes([num & 0xff]) # 常に1バイト 4 elif 256 > num >= 24: # 24..255の範囲 5 return bytes([0x18, num & 0xff]) # 常に2バイト 6 else: 7 raise NotImplementedError("no supported out of number 0..255")

※注意。ここでは、理解しやすくするために「数値のリスト」を用いてますが、
実際にバイナリを必要とする場面は、処理速度・省メモリ等の面での
最適化が求められることが多いので、より効率の良い方法で実装されます。

長さ23迄の配列

  • JSON では、配列の始点終点の [] に2バイト、区切り文字で 要素数-1の3バイト + データ(1234)の4バイト (2+3+4=計9バイト)
  • CBOR では1バイト目に配列であることの印とその長さの情報を含みます

小さな数(0..23)の配列であれば、そのデータサイズは 1+要素数

python

1def cbor_encode_array(seq): 2 # 長さ23迄の配列 3 assert len(seq) < 24 4 result = bytearray([0x80 | len(seq)]) 5 for val in seq: 6 result.extend(cbor_encode(val)) 7 return bytes(result) 8 9def cbor_encode(value): 10 if isinstance(value, int): 11 return cbor_encode_number(value) 12 elif isinstance(value, list): 13 return cbor_encode_array(value) 14 else: 15 raise NotImplementedError("unknown data type") 16 17if __name__ == '__main__': 18 print(repr(cbor_encode(0))) # => b'\x00' 19 print(repr(cbor_encode(23))) # => b'\x17' 20 print(repr(cbor_encode([1,2,3,4]))) # => b'\x84\x01\x02\x03\x04'

参考・関連

要バイナリに関する基礎知識:
ビット、バイト、16進数、2進数、補数、バイトオーダー、エンディアン、辺り

実際に自分で実装となると、この辺を参考にすると思います。

投稿2020/03/25 02:14

編集2020/03/25 05:40
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pokemonta

2020/03/26 01:42 編集

説明ありがとうございます。 何点か追加で質問させて頂きたいことがございます。 ①. [1,2,3,4] \x84 \x01 \x02 \x03 \x04 に関しまして、以下のサイトを参照しますと https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_71/network/conversion_table.html 16 進数とASCIIは以下の通りでした。 [ 5B , 2C ] 5D 従いまして、以下のような値にならないでしょうか? [1,2,3,4] \x5B \x01 \x2C \x02 \x2C \x03 \x2C \x04 \x5D \x84がどこから出てきたのか教えて頂けないでしょうか 参考情報 [1, 2, 3] | 0x83010203 https://tools.ietf.org/html/rfc7049#page-41 ②. 0..23 の範囲の整数に関しまして 『CBORでは変換なし。サイズは常に1』があまり理解できませんでした。 以下のサイトを参照しますと <https://geeks-world.github.io/articles/J208690/index.html?Trustwave-Auth=e1de90646e921dd470811811ac1272670b75eb7eBwl28VCimmwR36JwuQQ8vFrqRuz4JLGcvpdFOUO3Qy0RGqQ8U+yHOtTH9mIVUnoOl+CJ8K4cot7l27H8IVyQWkGgXHx5qbKPBoZo7wFJ06zJqfKH3s4tULWSwvY4elBoEtAmNQDQR2PqoSCAaepHUF5huaQAJQGkIdAZhR3UI/8+3lzKAsIsWz9e/m/y4hkZxN9RC3IMCpHytMvlVlfcP/gN7cu5VTa4Vh+sJcgO2ZNDnhxk6x3+Ag==> 型の指定でMajor Type = 0、Additional Information = 23を 指定した場合、非負整数(タイプ0)で値23バイト使えることを表現できるとの認識です。(半角英数字なら23文字) サイズは常に1は、何を指しているのでしょうか?
pokemonta

2020/03/25 06:15

\x84は、データ構造と要素数みたいですね。 これはASCIIを16進数に変換するのではなくCBORの仕様みたいです。 上記追加質問①については理解できたのですが、要素が多くなると 数えるのが大変ですし、\x8f以上の要素を作れないのではないでしょうか map(2) ⇒ A2 Array of length 3 ⇒ 83
teamikl

2020/03/25 08:04 編集

> \x84がどこから出てきたのか教えて頂けないでしょうか > 0x80..0x97 | array (0x00..0x17 data items follow) タイプ4:要素の配列 配列を表す 0x80 | 配列の長さ 0x00 .. 0x17 (10進数で 0..23) 迄を組み合わせ [1, 2, 3] | 0x83010203 に合わせて書くと [1, 2, 3, 4] は 0x8401020304 \x84 がどこからというのは、値をビットとして見る必要があります。 下URLの図で Major Type 3bits + Additional 5 bits というのがわかると思いますが Major Type 4 (0b100) + Additional 0..23 (0b00000 .. 0b10111) 組み合わせると、2進数で 0b10000000 .. 0b10010111 (16進数では 0x80 .. 0x97) 8というのは 配列を示すMajor Type 4 が、Additional と合わせて 16進数で表示する時 1 ビット左にシフトするため(4<<1)=8 という風に現れます。 ちなみに、長さ 16以上 の時は上位4ビットは 0b1001 となるため16進数で 0x9[0-7] になります。 \x84 について2進数で表すと 0b100000100 上位3bitsの 0b100 が Major typeの4,下5bits 0b00100 が配列の長さの4 \x5B \x01 \x2C \x02 \x2C \x03 \x2C \x04 \x5D [] や , を含むのは JSONの場合です。また JSON の場合は数値も ASCII で表現になります JSONの"[1,2,3,4]"をバイト列で表す場合 \x5B \x31 \x2C \x32 \x2C \x33 \x2C \x34 \x5B > 型の指定でMajor Type = 0、Additional Information = 23を指定した場合、 > 非負整数(タイプ0)で値23バイト使えることを表現できるとの認識です。(半角英数字なら23文字) これは No Major=0 のときは、Additional Information の 全5bits (十進数で 2**5 = 0..32) のうち 0..23 迄はそのままデータの値になります 24..27 はそれ以上の値を表すときの型情報となります。 Additional Information の役割は Major Type により変わります。 例)「タイプ7:浮動小数点数およびその他の単純なデータ型」 > サイズは常に1は、何を指しているのでしょうか? は、「なぜサイズが違うのかが全然わかりません」にかかってます、 エンコード後のデータのサイズです。
teamikl

2020/03/25 07:25 編集

> \x8f以上の要素を作れないのではないでしょうか 16進数で5ビットが配列サイズのために使えるので、0x97 (0x80+長さ23)まではそのまま作れます。 それ以上になると、1バイト内に長さが収まらないため 整数で24以上のときと同様に1バイト目は 0x98..0x9b とし それ以上の長さをその次のデータから読み込みます。 また任意の長さの配列は、 | 0x9f | array, data items follow, terminated by "break" | 0xff | "break" stop code 終端を表す 0xff が現れるまでとなります。
pokemonta

2020/03/26 01:56

ご回答ありがとうございます。 以下の回答に関しまして >Major=0 のときは、Additional Information の 全5bits (十進数で 2**5 = 0..32) のうち >0..23 迄はそのままデータの値になります >24..27 はそれ以上の値を表すときの型情報となります。 整理ましたので確認頂けないでしょうか 0~23の場合 000 10111(Major Typeが0、Additionalが23の時) ”そのままデータの値となります”とは、 23桁のinteger を表すという意味ではなく 1バイトで00000...10111(0...23)を表現するという意味でしょうか? 24~27の場合 000 11000(Major Typeが0、Additionalが24の時) "24..27 はそれ以上の値を表すときの型情報となります"とは 2バイトで00000000 00011000~00000000 11111111(24...65535)まで 表現するという意味でしょうか?
pokemonta

2020/03/26 05:11

2バイト表現なので255を表現したい時は このようになるということですね。<24,255>
teamikl

2020/03/26 07:52 編集

概ねあってそうだけど、ここが違います。 ここでの2バイトというのは、 major_type と additional info を含んだサイズです X: 00000000 00011000~00000000 11111111(24...65535 O: 00011000 00011000~00011000 11111111(24...65535 1バイト目 major_type 0b000, additional 0b11000 2バイト目 255 (0xff, 0b1111111) (255の数値自体は 1バイト=8ビット 2**8=256 のギリギリ範囲内) 1バイト目にはmajor_type(3bits) が有るため、値自体に使えるのは残りの5bit 5bits内では (2**8) 0..31 までしか表現できないうち、 型の拡張にも値が使われるため、 数値: 24~255は2バイト「目」に 1バイト目(major_type, additional) 0b00011000 と 2バイト目(0b00011000~0b11111111) 24..255 合計での2バイトになります。 (※ 0b0000 2進数表記, 0x00 16進数表記) 追記 >2バイト表現なので255を表現したい時は >このようになるということですね。<24,255> ここはそのとおりです。24 (0x18, 0b00011000) が1バイト目の major_typeとadditional
teamikl

2020/03/26 08:13 編集

> "24..27 はそれ以上の値を表すときの型情報となります"とは >2バイトで00000000 00011000~00000000 11111111(24...65535)まで 24 (0x18) の時は 1バイト(8bit数値) 24..65535 (8ビットで表せる範囲 25 (0x19) の時は 2バイト(16bit数値) 65536 ... (2**16)-1 (16ビットで表せる範囲 26 (0x20) の時は 4バイト(32bit数値) (2**16) .. (2**32)-1 (32ビットで表せる範囲 27 (0x20) の時は 8バイト(64bit数値) ~となります。(CBOR仕様Major type 0より)
pokemonta

2020/03/29 05:07

ありがとうございました。↓が何を表してるかはわかりませんでした。 X: O: あと、24 (0x18) の時は 1バイト(8bit数値) 24..65535 (8ビットで表せる範囲 ではなく、24,..255ではないでしょうか
teamikl

2020/03/29 10:08 編集

すいません、ずれてますね。 24..255 です 16ビットでの値の範囲は 256..65535 >"24..27 はそれ以上の値を表すときの型情報となります"とは 2バイトで00000000 00011000~00000000 11111111(24...65535)まで0> 表現するという意味でしょうか? X: 00000000 00011000~00000000 11111111(24...65535 O: 00011000 00011000~00011000 11111111(24...255 訂正 の部分。2進数で見た時の表記です。 ここの「2バイト」が何処を指しているのか解りませんが、 24..27の時、その後に続くデータのサイズは可変なので、 00000000 00011000 のようにはなりません。 型情報を含む場合は 00011000 00011000 の計2バイト、 もしくはデータ部分のみをさす場合は 00011000 の1バイトになります。
guest

0

「python CBOR」でググると、1番目と2番目に以下のモジュールが出てきました。
cbor · PyPI
cbor2 · PyPI

投稿2020/03/25 01:37

Lhankor_Mhy

総合スコア36115

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問