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

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

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

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

Q&A

解決済

4回答

266閲覧

packされたbytes型データの質問

slimat

総合スコア57

Python

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

0グッド

0クリップ

投稿2018/11/29 12:35

編集2018/11/29 13:18

こんにちは。

以下のpythonのstructモジュールに関しての記事にて分からないところがありました。
下記コードは下記リンク先に載っていたものです。
リンク内容

python

1data = pack('hhl', 1, 2, 3) 2data 3#b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00'

コードのようにやると、コメントのようにpackされるとのことなのですが、h,lはそれぞれ2,4バイトで処理すると書いていて、全部で8バイトにならないのか?と思いました。
スラッシュとスラッシュとの間が1バイトだと考えているので、全部で16バイトになっています。
私の解釈のどこが間違っているのでしょうか?

よろしくお願い致します。

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

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

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

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

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

can110

2018/11/29 12:53

コメントのような結果が再現できません。実際に実行した結果を追記ください。
slimat

2018/11/29 13:16

すみません、記述ミスがありました。コードは全てサイト(リンク)に載っていたものです。
guest

回答4

0

ベストアンサー

リファレンスより:

7.1.2.1. バイトオーダ、サイズ、アラインメント(原文)

デフォルトでは、C での型はマシンのネイティブ (native) の形式およびバイトオーダ (byte order) で表され、適切にアラインメント (alignment) するために、必要に応じて数バイトのパディングを行ってスキップします (これは C コンパイラが用いるルールに従います)。

ということで、環境により、デフォルトでは8バイト境界にアラインメントされるようです。=でアラインメントを抑止できます。

Python

1pack('=hhl', 1, 2, 3) 2#=> b'\x01\x00\x02\x00\x03\x00\x00\x00'

Windowsだと、デフォルトでもアラインメントされませんでした。

投稿2018/11/29 13:16

otn

総合スコア84499

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

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

slimat

2018/11/29 15:24

回答ありがとうございます。 =をつけた結果がそのようでしたら、納得できます! 只、もしも1、2、3、のような小さな値ではなく、1を256?に変えた場合には b'/xff/x01/x00/x02/x00/x03/... のようになるのでしょうか?
otn

2018/11/29 15:29

511, 2, 3 を指定したらそうなりますね。
slimat

2018/11/29 15:40

511?! xffは255だと思っていたのですが、合っているのでしょうか?
hayataka2049

2018/11/29 18:58 編集

hはshortで2byte整数なので、01ffで511です。リトルエンディアンなので。ただ、\x01のあとの\x00が余計ですが。あと、/xじゃなくて\xですが(バックスラッシュ)。 >>> struct.pack('=hhl', 511, 2, 3) b'\xff\x01\x02\x00\x03\x00\x00\x00'
slimat

2018/11/30 08:25

回答ありがとうございます。 xffの後にx01/x00となることを忘れていました。 macキーボードなんですけど、キーが見当たらないなと思っていたところ、調べることで解決しました。
guest

0

アラインメント・パディング絡みじゃないですかね。私の環境はlinux 64bitです。

python

1>>> import struct 2>>> struct.pack("hhl", 1,2,3) 3b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00' 4>>> struct.pack("@hhl", 1,2,3) 5b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00' 6>>> struct.pack("=hhl", 1,2,3) 7b'\x01\x00\x02\x00\x03\x00\x00\x00' 8>>> struct.pack("<hhl", 1,2,3) 9b'\x01\x00\x02\x00\x03\x00\x00\x00' 10>>> struct.pack(">hhl", 1,2,3) 11b'\x00\x01\x00\x02\x00\x00\x00\x03'

デフォルトでは、C での型はマシンのネイティブ (native) の形式およびバイトオーダ (byte order) で表され、適切にアラインメント (alignment) するために、必要に応じて数バイトのパディングを行ってスキップします (これは C コンパイラが用いるルールに従います)。

7.1. struct — バイト列をパックされたバイナリデータとして解釈する — Python 3.6.5 ドキュメント

投稿2018/11/29 13:06

編集2018/11/29 13:21
hayataka2049

総合スコア30933

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

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

slimat

2018/11/29 15:26

回答ありがとうございます。 そのようなことが原因だったのですね!理解できました。
guest

0

実行環境のshortint型のサイズによります。
一般的なサイズは7.1.2.2. 書式指定文字に記載されていますが
提示サイトの実行環境ではshort4bytelong8byteなのだと思われます。

ちなみに当方環境Win10Python 3.5.6 |Anaconda custom (64-bit)| (default, Aug 26 2018, 16:05:27) [MSC v.1900 64 bit (AMD64)] on win32ではb'\x01\x00\x02\x00\x03\x00\x00\x00'となりました。

7.1.2.3. 使用例でもpack('hhl', 1, 2, 3)の結果はb'\x00\x01\x00\x02\x00\x00\x00\x03'と記載されています。
ここで\0x01などの順番が異なるのは、マシンのエンディアンの違いによるものなので無視してよいです。

投稿2018/11/29 13:13

can110

総合スコア38262

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

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

can110

2018/11/29 13:20

サイズというよりアライメントするかどうかの違いのようですね。微妙にずれた回答でした…
slimat

2018/11/29 15:33

回答ありがとうございます。 リトルエンディアンだと、 b'/x00/x01/と書かれているように、前の方にパディングするのですね!
guest

0

macOS(10.14.1, Mojave)では以下のような結果でした。

python

1from struct import pack 2 3pack('@hhl', 1, 2, 3) 4# b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00' 5pack('hhl', 1, 2, 3) 6# b'\x01\x00\x02\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00' 7pack('<hhl', 1, 2, 3) 8# b'\x01\x00\x02\x00\x03\x00\x00\x00'

投稿2018/11/29 13:28

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

slimat

2018/11/29 15:29

回答ありがとうございます。 また今度、<をつけることの意味を調べてみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問