ソフトな忘却力(29) uuid、libuuidでパースして比較、wsl2、Ubuntu

Joseph Halfmoon

今回はUUIDです。たまに登場するやたら長い(128ビット)IDです。勝手に生成しても(高い確率で)衝突しないIDなんだと。Bluetoothなどの通信でも登場し言われたとおりに書き写すしかない?アレです。手元のwsl2上のUbuntu20.04LTSでは、何も言わずにインストール済というかOSの一部になっている?

※「ソフトな忘却力」投稿順 Index はこちら

※実行確認はWindows11上のWSL2にのせてあるUbuntu20.04LTSで行ってます。

UUID

Universally Unique Identifier、日本語にすると「ユニバーサル固有識別子」だそうです。グローバルにユニークであることがほぼほぼ保障されている128ビット長の数値です。

以下で規定されているみたいです。

    • ITU-T X.667
    • ISO/IEC 9834-8:2005

ITUもISOも検索すれば規格はすぐに見つかりますが、大きな組織のサイトは荘厳で即座に肝心のドキュメントにたどり着けないのが難点。その点以下のRFCドキュメントはクリックすれば本文に突入。お手軽。

RFC4122

また、マイクロソフト様版的なGUID(Globally Uniq Identifier)というものもあり、これはUUIDとほぼほぼ等価みたいです。詳しくはマイクロソフト様にお聞き。

またBLE(Bluetooth Low Energy)みていると、無線通信用に16bitとか32ビットの「UUIDの短縮形」なるものが登場するのですが、これはBluetooth SIG側の規定で内輪のお約束みたいです。知らんけど。まあBluetoothが確保してある?UUIDの世界の中では、短縮形からフルUUIDに膨らませることが可能みたい。

Ubuntu 20.04LTS上でのインストール状況

今回 libuuid をちょいと使ってみるべい、ということでインストール状況を確認したら、手元のUbuntuでは、libuuidだけでなくuuid-devもuuid-runtimeも最初からインストール済だったです。というのもLinuxの奥深くに組み込まれて使われているためみたい。uuid関係のライブラリやツールはutil-linuxパッケージというものの一部でそれが組み込まれておるみたいっす。

ドキュメントも

info uuid

でも

man uuid

でも読めます(多分同じ内容ですが、infoの方がリンクをたどれてお楽。)

UUIDを生成する

お手軽に uuid 文字列を一個「振り出す」場合、以下のようにcatすればGETできます。UUIDex0

上記で2か所赤色マーカしてある桁がありますが、これはバージョンとバリアントの桁です。バリアントの方は上記のドキュメント読んでくだされ(その割に決定的な役割は果たさないけれど。)バージョンの「4」の方からは、このUUIDが乱数ベースで生成されたもの、ということがわかります。まあrandomの配下にあるし、あたりまえか。

また、Linuxコマンドとして uuidgen がインストールされているので、これを使えば「バージョン」違う作り方のUUIDを得ることができます。

まずは今回使用のuuidgenVersionuuidgen自体のバージョンが以下に。

 

タイムスタンプを使った、バージョン1形式のUUIDをGETするときは以下のように。UUIDexT

–randomとすると先ほどのcatと同じバージョン「4」形式になるみたいです。まあ、生成方法のバージョン変わったところで128ビットのIDであることは変わらず。使うときは一緒ってか。

勿論、libuuid 内にもUUID生成関数が定義されているので、これを呼び出して使えばUUIDを生成できると思います(やってないけど。)今回は上記のようにすでにUUIDが「振り出されて」あったときに、UUIDの文字列を数値変換してコンペアかけるところを練習してみたいと思います。

実験用ソース(C言語)作成して実行

作製してみたソースが以下です。さきほど cat で読みだしたUUIDとの一致、不一致を調べるだけのものです。

#include <stdio.h>
#include <stdlib.h>
#include <uuid/uuid.h>

int main(int argc, char const *argv[]) {
    uuid_t uuidIn;
    uuid_t uuidCmp;
    if (argc < 2) {
        fprintf(stderr, "ERROR: No UUID string found.\n");
        exit(EXIT_FAILURE);
    }
    printf("Input UUID:%s\n",argv[1]);
    if (uuid_parse(argv[1], uuidIn) == 0) {
        uuid_parse("072fd41d-3c2f-4e7d-b417-b0af628ff47f", uuidCmp);
        if (uuid_compare(uuidIn, uuidCmp) == 0) {
            printf("UUID matched.\n");
        } else {
            printf("UUID unmached.\n");
        }
    } else {
        fprintf(stderr, "ERROR: Illegal UUID.\n");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

コンパイルは以下です。立派にインストールされているので pkg-configも使えます。

$gcc parseUUID.c $(pkg-config --cflags --libs uuid)

マッチする筈の文字列を与えたところが以下に。16進数の一部を大文字にしてみているけれど。大丈夫。Matched1

続いて最下位桁を「改ざん」してみたもの。ちゃんと unmachedじゃ。UnMatched1

そもそも形式が不良なもの。Illegalだと。Illegal

UUID、使える気がしてきた。ホントか?

ソフトな忘却力(28) libqrencode、ソースからインストールして使ってみた編 へ戻る

ソフトな忘却力(30) SQLite3をC言語から使う。Amalgamationって何よ。 へ進む