JavaScript(ESM)とPHPで圧縮・解凍
JavaScriptとPHP間で、データの圧縮・解凍を調べたのでまとめていく
今回は、「pako」というライブラリを見つけたのでそちらを基に作成
参考
サンプルコード
5つのテストデータを用意した
テストを生成するにあたって、サンプルコードを用意しようと思ったけどめんd… 大変だったので、Claude3.5君に一部お願いしました
間違ってたらごめんです
テストデータ
1つ目 [ 当ブログのキャッチコピー? ]
I/O習慣を身に付ける!ロクの技術録
2つ目 [ 文字数:300 バイト数:300B ]
TFYPfLzEEBNmWUvFeTrahHRqFfdwawtJCHvCZlHEgRescPbXSRMXZnuQoeUAKyOcPxgrkmXchWHauWgtrKELVCRasLmfRUIgTrbMOpyTSIvJkTEWOCrofCPHUitsEYdOmWttkDKFjdHbZVryAtKVYiFIQjmJZTstdtFHhvtuUNhfbNjraWunhTLCxHIGHaFzrKhihTOlNlSQyntyQGZtVZLTxjuhZvCDksdeUjtKEmIJnBNIOLeuRMjNhrIPBPBKiteEZEIYHLJFLZHdAkbabEjXUwtYxbJtFuYxohjYOTUM
3つ目 [ 文字数:300 バイト数:900B ]
人道ゆか字火フ海本家チふなわ社エうソハミムマ土ヤつテもヘひはつヨヲ家わめミ日あてメスわをそ人ちヘテふろコスますソ日きむツへ小ケ雪そネほやそひ道りロやトやなリ店くゆう日ムわて会ルへわはとほふ火たコリく空会ハ電レにナノ海休たみナシヲ道トルヒせ家木ヘケむサウホしヨ会ヌとナ店フたコラわ人テ休か木へこソとスにせムルヲス会オヲフなれア車ラ金大空りたくツつ中ラメ空マナほル休にれコゆヌすふ金タ本ちロよリワコすはセナソよえにもン水アつンゆチこリ山はやツヤこねふぬエウにムカとア水ンニ休キふ本まムワちもテセけも木ロ社ノ車ムけ家キおも空おつ駅ム金ムこあオこウかト中ロツゆひ会ふウノノふクむめうおにルスめるまけいねりアい
4つ目 [ 文字数: 300 バイト数:738B ]
みむねタ字ハ駅ミさoくDFヲムインとイワモカZYくこヨむヲ年kト文にチトもまノ9んあナハb大ゆホたAyユえねvむ5ニるそwエルqへ火空ヒKすけさへuクゆ人MむかWtm火サ4フAg水国つqjpEzU木Drワn3ノ生空よウ休れJに店ねニovND車スxたモ家ぬかuヲエ大ヨエヘGうEア空ミヨおロゆクえさりみNちとなxd国休uす川58ムヨ7家ツニんト休カ社う大gA店カクやX店りナころL7駅文ミま文川7vノみくカVコ9よ休海車U小Rねマuそ小生道会sセ9中ロたけろQdく川字めJ電家ぬ駅lニ休つみハ駅めきカ店コUユ空MをrトMわトふ年う4木h本るeよやぬなテUVfいアムとヤ木Hカ本Gいヌさワホa年ユワFせに
5つ目 [ オブジェクト 文字数:461 バイト数: 494B ]
{
"id": 1,
"userId": "USER_Lk9nM4pX",
"username": "johndoeXYZW",
"nickname": "すずキ",
"email": "test8nK4@example.com",
"age": 45,
"prefecture": "東京",
"address": "大阪市中央区北浜なかの",
"phone": "09012345678",
"company": {
"name": "未来テクノ株式会社",
"department": "営業部",
"position": "主任まねぎ"
},
"status": "active",
"points": 8742,
"lastLogin": "2024-01-15T08:23:45.000Z",
"createdAt": "2022-05-20T14:30:00.000Z",
"updatedAt": "2024-12-22T10:00:00.000Z"
}
JavaScript (テストコード)
圧縮
function encodeData(data){
// pakoライブラリのgzip関数で、データを圧縮
const binaryData = pako.gzip(data, {to: "string"});
// バイナリ文字列をUTF-16に変換
const strEncodeData = String.fromCharCode.apply(null, binaryData);
// Base64に変換
return btoa(strEncodeData);
}
解凍
function decodeData(data){
// Base64に変換
const binaryString = atob(data);
// バイナリ文字列をUint8Arrayに変換
const byteArray = new Uint8Array(binaryString.split('').map(char => char.charCodeAt(0)));
// pakoライブラリのデータを解凍
return pako.inflate(byteArray, {to: "string"});
}
PHP (テストコード)
圧縮
function encodeData($data): string
{
// GZipでデータを圧縮
$compressedData = gzencode($data);
// Base64に変換
return base64_encode($compressedData);
}
解凍
function decodeData($data): false|string
{
// Base64をデコード
$decodedData = base64_decode($data);
// GZipデータを解凍
return gzdecode($decodedData);
}
サンプルコード全体
<?php
$test1 = "I/O習慣を身に付ける!ロクの技術録";
$test2 = "TFYPfLzEEBNmWUvFeTrahHRqFfdwawtJCHvCZlHEgRescPbXSRMXZnuQoeUAKyOcPxgrkmXchWHauWgtrKELVCRasLmfRUIgTrbMOpyTSIvJkTEWOCrofCPHUitsEYdOmWttkDKFjdHbZVryAtKVYiFIQjmJZTstdtFHhvtuUNhfbNjraWunhTLCxHIGHaFzrKhihTOlNlSQyntyQGZtVZLTxjuhZvCDksdeUjtKEmIJnBNIOLeuRMjNhrIPBPBKiteEZEIYHLJFLZHdAkbabEjXUwtYxbJtFuYxohjYOTUM";
$test3 = "人道ゆか字火フ海本家チふなわ社エうソハミムマ土ヤつテもヘひはつヨヲ家わめミ日あてメスわをそ人ちヘテふろコスますソ日きむツへ小ケ雪そネほやそひ道りロやトやなリ店くゆう日ムわて会ルへわはとほふ火たコリく空会ハ電レにナノ海休たみナシヲ道トルヒせ家木ヘケむサウホしヨ会ヌとナ店フたコラわ人テ休か木へこソとスにせムルヲス会オヲフなれア車ラ金大空りたくツつ中ラメ空マナほル休にれコゆヌすふ金タ本ちロよリワコすはセナソよえにもン水アつンゆチこリ山はやツヤこねふぬエウにムカとア水ンニ休キふ本まムワちもテセけも木ロ社ノ車ムけ家キおも空おつ駅ム金ムこあオこウかト中ロツゆひ会ふウノノふクむめうおにルスめるまけいねりアい";
$test4 = "みむねタ字ハ駅ミさoくDFヲムインとイワモカZYくこヨむヲ年kト文にチトもまノ9んあナハb大ゆホたAyユえねvむ5ニるそwエルqへ火空ヒKすけさへuクゆ人MむかWtm火サ4フAg水国つqjpEzU木Drワn3ノ生空よウ休れJに店ねニovND車スxたモ家ぬかuヲエ大ヨエヘGうEア空ミヨおロゆクえさりみNちとなxd国休uす川58ムヨ7家ツニんト休カ社う大gA店カクやX店りナころL7駅文ミま文川7vノみくカVコ9よ休海車U小Rねマuそ小生道会sセ9中ロたけろQdく川字めJ電家ぬ駅lニ休つみハ駅めきカ店コUユ空MをrトMわトふ年う4木h本るeよやぬなテUVfいアムとヤ木Hカ本Gいヌさワホa年ユワFせに";
$test5 = json_encode([
"id" => 1,
"userId" => "USER_Lk9nM4pX",
"username" => "johndoeXYZW",
"nickname" => "すずキ",
"email" => "test8nK4@example.com",
"age" => 45,
"prefecture" => "東京",
"address" => "大阪市中央区北浜なかの",
"phone" => "09012345678",
"company" => [
"name" => "未来テクノ株式会社",
"department" => "営業部",
"position" => "主任まねぎ"
],
"status" => "active",
"points" => 8742,
"lastLogin" => "2024-01-15T08:23:45.000Z",
"createdAt" => "2022-05-20T14:30:00.000Z",
"updatedAt" => "2024-12-22T10:00:00.000Z"
]);
function encodeData($data): string
{
// GZipでデータを圧縮
$compressedData = gzcompress($data);
// Base64に変換
return base64_encode($compressedData);
}
function decodeData($data): false|string
{
// Base64をデコード
$decodedData = base64_decode($data);
// GZipデータを解凍
return gzuncompress($decodedData);
}
function characters($data): int
{
return strlen($data);
}
function sizeCount($data): int
{
return strlen($data);
}
$tests = [$test1, $test2, $test3, $test4, $test5];
foreach ($tests as $index => $test) {
$result = encodeData($test);
$decodeResult = decodeData($result);
echo "========================================================================================\n";
echo "文字数 " . characters($result) . " サイズ " . sizeCount($result) . "\n";
echo $result . "\n";
echo $decodeResult . "\n";
assert($test === $decodeResult, "Test " . ($index + 1) . " failed");
}