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?

UUIDの長さを圧縮する

Last updated at Posted at 2025-04-29

目的

UUIDは様々なシステムで広く使われていますが、URLのパラメータとして渡そうとする時はやはりサイズが長いと思っています。
UUIDのバイナリー本質は16バイトの文字列なので、その素のデータを渡せば、かなり短縮できると考えています。

方法

For JS

UUID <=> Base64

const uuid = require('uuid');

// UUID => Binary Array => Base64 Str(URL-safe)
const binArray = uuid.parse('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b');
// Uint8Array(16) [
//   110, 192, 189, 127,  17,
//   192,  67, 218, 151,  94,
//    42, 138, 217, 235, 174,
//    11
// ]

function base64encode(binaryArray) {
  const b64Str = btoa([...binaryArray].map(n => String.fromCharCode(n)).join(""));

  return b64Str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
}

console.log(base64encode(binArray));
// 'bsC9fxHAQ9qXXiqK2euuCw'


// Base64 Str(URL-safe) => Binary Array => UUID
function base64decode(base64Str) {
  let str = base64Str.replace(/-/g, '+').replace(/_/g, '/');
  if (str.length % 4) str += '='.repeat(4 - str.length % 4); // pad with '='
  const binArr = atob(str).split('').map(c => c.charCodeAt(0));

  return new Uint8Array(binArr);
}

const uuidBin = base64decode('bsC9fxHAQ9qXXiqK2euuCw');
// Uint8Array(16) [
//   110, 192, 189, 127,  17,
//   192,  67, 218, 151,  94,
//    42, 138, 217, 235, 174,
//    11
// ]

console.log(uuid.stringify(uuidBin));
// '6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b'

For Ruby

UUID <=> Base64

# NPM package "uuid" の "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b" を例として
uuid = "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b" # 36文字

require "base64"
## UUID => BinaryStr => Base64 (URL Safe)
### uuidをBinaryStrに変換
bin_str = [uuid.gsub("-", "")].pack("H*")
# => "n\xC0\xBD\x7F\x11\xC0C\xDA\x97^*\x8A\xD9\xEB\xAE\v"

### Base64 (URL Safe) に変換
b64_str = Base64.urlsafe_encode64(bin_str, padding: false)
# => "bsC9fxHAQ9qXXiqK2euuCw" # 22文字、約40%圧縮

## Base64 (URL Safe) => ByteArray => UUID
### Base64 (URL Safe) からバイト列に変換
byte_arr = Base64.urlsafe_decode64("bsC9fxHAQ9qXXiqK2euuCw").unpack("C*")
# => [110, 192, 189, 127, 17, 192, 67, 218, 151, 94, 42, 138, 217, 235, 174, 11]

### バイト列を元にUUID文字列を生成
# positions = [[3, 2, 1, 0], [5, 4], [7, 6], [8, 9], 10..15] # C#のGUIDの仕様
positions = [0..3, 4..5, 6..7, 8..9, 10..15] # NPM package "uuid" の仕様 ("uuid.stringify()" に準拠)
uuid_str = positions.map {| a | a.map {| n | "%02x" % byte_arr[n] }.join }.join("-")
# => "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b"

Base64版UUID(もどき)を直接発行(厳密ではない)

require "securerandom"
require "base64"
# SecureRandom.uuid を使わず、Base64版を直接発行
SecureRandom.urlsafe_base64(16, false)
# => "h8JcfNDRGzoPc3pNiV88Bw"

# Base64版をUUIDに変換
arr = Base64.urlsafe_decode64("h8JcfNDRGzoPc3pNiV88Bw").unpack("C*")
[0..3, 4..5, 6..7, 8..9, 10..15].map {| a | a.map {| n | "%02x" % arr[n] }.join }.join("-")
# => "87c25c7c-d0d1-1b3a-0f73-7a4d895f3c07"

For Python

UUID <=> Base64

import base64
import uuid

uuid_str = "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b"
uuid_bytes = uuid.UUID(uuid_str).bytes

[int(byte) for byte in uuid_bytes]                   
# [110, 192, 189, 127, 17, 192, 67, 218, 151, 94, 42, 138, 217, 235, 174, 11]

base64_str = base64.urlsafe_b64encode(uuid_bytes).rstrip(b'=').decode('utf-8')
# bsC9fxHAQ9qXXiqK2euuCw

padding = '=' * ((4 - len(base64_str) % 4) % 4)
uuid_bytes = base64.urlsafe_b64decode(base64_str + padding)

uuid.UUID(bytes=uuid_bytes)
# UUID('6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b')

メソッド化

下記コードはGitHub Copilotより生成

import base64
import uuid

# UUID => Binary Array => Base64 Str (URL-safe)
def uuid_to_base64(uuid_str):
    # Convert UUID string to bytes
    uuid_bytes = uuid.UUID(uuid_str).bytes
    # Encode bytes to Base64 (URL-safe)
    base64_str = base64.urlsafe_b64encode(uuid_bytes).rstrip(b'=').decode('utf-8')
    return base64_str

# Base64 Str (URL-safe) => Binary Array => UUID
def base64_to_uuid(base64_str):
    # Decode Base64 (URL-safe) to bytes
    padding = '=' * ((4 - len(base64_str) % 4) % 4)  # Add padding if necessary
    uuid_bytes = base64.urlsafe_b64decode(base64_str + padding)
    # Convert bytes to UUID string
    return str(uuid.UUID(bytes=uuid_bytes))

# Example usage
original_uuid = "6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b"
print("Original UUID:", original_uuid)

# Convert UUID to Base64
base64_str = uuid_to_base64(original_uuid)
print("Base64 (URL-safe):", base64_str)

# Convert Base64 back to UUID
converted_uuid = base64_to_uuid(base64_str)
print("Converted UUID:", converted_uuid)

あわせ読み

参考

JS

Ruby

Python

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?