0
0

各種言語のBase64文字列の取り扱い

Posted at

はじめに

各種システムとのデータ連携にあたってBase64文字列を用いるシーンが偶にあり、各言語でどういった実装をするのかを毎回悩むため整理してみました。(※サンプルコードはdockerにて動作確認済み)

各言語の実装

1.PHP

main.php
<?php

$text="{'name':'山田太郎','address':'東京都港区'}";
echo base64_encode($text); # eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9
echo "\n";

$text = 'eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9';
echo base64_decode($text); # {'name':'山田太郎','address':'東京都港区'}
echo "\n";

?>
$ docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.2-cli php main.php

2.java

Main.java
import java.util.Base64;

public class Main {
    public static void main(String[] args){
        String text = "{'name':'山田太郎','address':'東京都港区'}";
        System.out.println(Base64.getEncoder().encodeToString(text.getBytes()));
        // eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9

        text = "eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9";
        System.out.println(new String(Base64.getDecoder().decode(text)));
        // {'name':'山田太郎','address':'東京都港区'}
    }
}
docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp openjdk:11 bash -c 'javac Main.java; java Main; rm *.class;'

3.python

main.py
import base64

text = "{'name':'山田太郎','address':'東京都港区'}"
print(base64.b64encode(text.encode()).decode()) 
# eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9

text = "eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9"
print(base64.b64decode(text).decode())
# {'name':'山田太郎','address':'東京都港区'}

docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:3.13.0a2 python main.py

4.javascript

4-1.atobとbtoaを用いる方法 Part1

ブラウザ上およびnode.jsで動作する方法。

■参考 The "Unicode Problem" | MSDN

main.js
function encodeBase64(str) {
  const bytes = new TextEncoder().encode(str);
  const binString = String.fromCodePoint(...bytes);
  return btoa(binString);
}

function decodeBase64(base64) {
  const binString = atob(base64);
  return new TextDecoder().decode(Uint8Array.from(binString, (m) => m.codePointAt(0)));
}

let text = "{'name':'山田太郎','address':'東京都港区'}";
console.log(encodeBase64(text));
// eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9

text = "eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9";
console.log(decodeBase64(text));
// {'name':'山田太郎','address':'東京都港区'}
docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp node:21.4.0 node main.js

4-2.atobとbtoaを用いる方法 Part2

ブラウザ上およびnode.jsで動作する方法。※古いやり方。

■参考 解決策その 1 - 文字列をエンコードする前にエスケープする | MSDN
※参考サイトではescapeとunescapeを非推奨としているので、以下サンプルでは自前関数で代替してます。

main.js
const encodeBase64 = (str) => {
  let b = encodeURIComponent(str)
    .replace(/%.{2}/g, (match) => {
        return String.fromCharCode(parseInt(match.slice(1), 16));
    });
  return btoa(b);
}
const decodeBase64 = (str) => {
  let b = atob(str)
    .split('')
    .map((c) => {
      return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    })
    .join('');
  return decodeURIComponent(b);
}

let text = "{'name':'山田太郎','address':'東京都港区'}";
console.log(encodeBase64(text));
// eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9

text = "eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9";
console.log(decodeBase64(text));
// {'name':'山田太郎','address':'東京都港区'}

docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp node:21.4.0 node main.js

4-3.Bufferを用いる方法

node.js上で実行する場合はBufferを用いる方が簡単。

main.js
let text = "{'name':'山田太郎','address':'東京都港区'}";
console.log(Buffer.from(text).toString('base64'));
// eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9

text = "eyduYW1lJzon5bGx55Sw5aSq6YOOJywnYWRkcmVzcyc6J+adseS6rOmDvea4r+WMuid9";
console.log(Buffer.from(text, 'base64').toString());
// {'name':'山田太郎','address':'東京都港区'}
docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp node:21.4.0 node main.js

終わりに

JWTなどではBase64ではなく、Base64Urlを用いることになるのでもう少し工夫が入りますが別の機会に。

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