teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

ちょっとかえて、IPv4の話も追加。

2019/12/01 10:56

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  UUIDは128bitsの整数値です。メモリ上は一つの大きな整数値※として扱われています。UUIDを生成するとき、UUIDのバージョン毎に異なる規則に従ってこの一つの大きな整数値を生成します。つまり、プログラム内部ではただの整数値に過ぎないと言うことです。
11
11
 
12
- ※ 実際の所、Cを含めた多くの言語や環境では128bits整数値をそのまま入れられる固定長整数型は存在しないため、内部的には複数の整数値にわかれているか、16バイト列として管理されていると思われます。
12
+ ※ 実際の所、Cを含めた多くの言語や環境では128bits整数値をそのまま入れられる固定長整数型は存在しないため、内部的には複数の整数値にわかれているか、16オクテット列として管理されていると思われます。
13
13
 
14
14
  また、この一つの大きな整数値は、整数全体で一つの意味ではなく、あるビット範囲でフィールドと呼ばれる区切りがあります。例えば、あるフィールドの特定の部分がバージョンを示すなどの役割を持っています。
15
15
 
@@ -23,4 +23,6 @@
23
23
  2. 整数値16進数にして変換する。このとき、小文字を(`a`-`f`)を用いる。
24
24
  3. 特定の位置に`-`を挿入する。
25
25
 
26
- 実装によっては2.と3.は前後するかも知れません(わけてから`-`で繋ぐ)。ただ、(よほどおかしな実装ではない限り)基本的には最初に整数値を作成してから16進数の文字列に変換するのであり、文字列を直接生成しているわけではありません。
26
+ 実装によっては2.と3.は前後するかも知れません(わけてから`-`で繋ぐ)。ただ、(よほどおかしな実装ではない限り)基本的には最初に整数値を作成してから16進数の文字列に変換するのであり、文字列を直接生成しているわけではありません。
27
+
28
+ このように内部表現とテキスト表記が違うというような例としてIPアドレスがあります。IPv4は内部的にはただの4オクテット列であり、パケットの内部では4オクテット列として存在します。しかし、設定等や表現では4つの10進数(0から255)を`.`で区切るとしています。IPアドレスを扱うプログラムがIPv4のテキスト表記を扱うとき、16進数ではなく10進数を使う理由、1オクテット毎に`.`を区切りに使う理由というのはRFCでIPv4はそのように表記すると定められているから、そのように実装しているに過ぎません。UUIDについても同様で、各ライブラリはRFCに従っているだけに過ぎないと言うだけです。

1

内部表現とテキスト表記は異なるという話

2019/12/01 10:56

投稿

raccy
raccy

スコア21767

answer CHANGED
@@ -2,4 +2,25 @@
2
2
 
3
3
  > The hexadecimal values "a" through "f" are output as lower case characters and are case insensitive on input.
4
4
 
5
- と書かれているため、Pythonのuuidライブラリもその仕様に従っているだけです。
5
+ と書かれているため、Pythonのuuidライブラリもその仕様に従っているだけです。
6
+
7
+ ---
8
+ 【追記】
9
+
10
+ UUIDは128bitsの整数値です。メモリ上は一つの大きな整数値※として扱われています。UUIDを生成するとき、UUIDのバージョン毎に異なる規則に従ってこの一つの大きな整数値を生成します。つまり、プログラム内部ではただの整数値に過ぎないと言うことです。
11
+
12
+ ※ 実際の所、Cを含めた多くの言語や環境では128bits整数値をそのまま入れられる固定長整数型は存在しないため、内部的には複数の整数値にわかれているか、16バイト列として管理されていると思われます。
13
+
14
+ また、この一つの大きな整数値は、整数全体で一つの意味ではなく、あるビット範囲でフィールドと呼ばれる区切りがあります。例えば、あるフィールドの特定の部分がバージョンを示すなどの役割を持っています。
15
+
16
+ さて、プログラム内部で完結する場合は良いとして、データをやり取りする場合、特にテキストデータとしてやり取りする場合、そのまま10進数で整数として表現するにはあまりにも大きいです。また、フィールド毎の意味も10進数ではよくわからなくなってしまいます。そもそもUUIDはURNとして使えるものとして作られたため、テキストで表現できなければなりません。それが普段UUIDとして見ている16進数を`-`で区切ったフォーマットです。また特定位置を`-`で区切ることで、人の目からもフィールドを把握しやすくし、判別がしやすくなっています。(各場所がどのような意味になるのかはバージョンによって異なるため、一概には言えません)
17
+
18
+ この16進数を`-`区切りしたものもUUIDではありますが、これはURNとして表現であり、テキストデータとしてやり取りするときに使用するためのもので、プログラムの内部では依然として128bitsの整数値として扱われてます。つまり、それらを相互に変換する仕組みも定めなければなりません。そして、そのルールの一つとして16進数を使うのですが、内部表現の整数値からテキストとして出力する場合は小文字を使う、入力されたテキストを内部表現の整数値に変換するときは大文字小文字を無視するとなっているということです。
19
+
20
+ つまり、UUIDを生成し、そのテキストを得るするとき、プログラム内部は次のように動作しています。
21
+
22
+ 1. バージョン毎に定められた規則に従って128bitsの整数値を生成する。
23
+ 2. 整数値16進数にして変換する。このとき、小文字を(`a`-`f`)を用いる。
24
+ 3. 特定の位置に`-`を挿入する。
25
+
26
+ 実装によっては2.と3.は前後するかも知れません(わけてから`-`で繋ぐ)。ただ、(よほどおかしな実装ではない限り)基本的には最初に整数値を作成してから16進数の文字列に変換するのであり、文字列を直接生成しているわけではありません。