JavaScript で文字コードの変換や判定をします。
- 特徴
- インストール
- 対応する文字コード
- 使い方の例
- Demo
- API
- その他の例
- Contributing
- License
encoding.js は、文字コードの変換や判定をする JavaScript ライブラリです。
Shift_JIS
や EUC-JP
、ISO-2022-JP
など日本語の文字コードや、 UTF-8
、UTF-16
などの Unicode に対応しています。
JavaScript の文字列は内部で UTF-16 コードユニットとして符号化されるため、文字列のままでは他の文字コードを正しく扱えませんが (参照: ECMAScript® 2019 Language Specification - 6.1.4 The String Type)、encoding.js では文字列ではなく配列として扱い変換を実現しています。
各文字コードは、例えば [130, 160]
(Shift_JIS の「あ」) などの文字コード値を持つ数値の配列として扱います。
また、encoding.js の各メソッドに渡す文字コードの配列は、Uint8Array
などの TypedArray や Node.js の Buffer
でも使えます。
文字コードの数値配列から文字列には Encoding.codeToString
などのメソッドで変換できますが、JavaScript は上記の特徴があるため文字列化してしまうと文字コードによっては正しく扱えません。
そのため配列でなく文字列で扱いたい場合は、 Encoding.urlEncode
と Encoding.urlDecode
を通して '%82%A0'
のようなパーセントでエンコードされた文字列に変換すると、他のリソースに受け渡しが可能です。
または、Encoding.base64Encode
と Encoding.base64Decode
でも同様な方法で文字列として受け渡しができます。
npm では encoding-japanese
というパッケージ名で公開されています。
npm install --save encoding-japanese
import Encoding from 'encoding-japanese';
const Encoding = require('encoding-japanese');
encoding.js の TypeScript 型定義は @types/encoding-japanese から利用できます (@rhysd さんありがとうございます)。
npm install --save-dev @types/encoding-japanese
npm経由でインストールするか、またはリリース一覧からダウンロードしたパッケージ内の encoding.js
をご使用ください。
※ git clone
した場合は、master (または main) ブランチであっても開発中の状態の可能性がありますのでご注意ください。
<script src="encoding.js"></script>
minify された encoding.min.js
も使用できます。
<script src="encoding.min.js"></script>
ブラウザで読み込むと Encoding
というオブジェクトがグローバルに (window.Encoding
として) 定義されます。
<script>
タグで CDN から直接 encoding.js (パッケージ名: encoding-japanese
) を利用できます。
<script src="https://unpkg.com/[email protected]/encoding.min.js"></script>
この例では unpkg を使用していますが、 cdnjs や jsDelivr など npm パッケージを提供する他の CDN も利用できます。
encoding.js での値 | detect() |
convert() |
MIME名 (備考) |
---|---|---|---|
ASCII | ✓ | US-ASCII (コードポイントの範囲: 0-127 ) |
|
BINARY | ✓ | (バイナリー文字列。コードポイントの範囲: 0-255 ) |
|
EUCJP | ✓ | ✓ | EUC-JP |
JIS | ✓ | ✓ | ISO-2022-JP |
SJIS | ✓ | ✓ | Shift_JIS |
UTF8 | ✓ | ✓ | UTF-8 |
UTF16 | ✓ | ✓ | UTF-16 |
UTF16BE | ✓ | ✓ | UTF-16BE (big-endian) |
UTF16LE | ✓ | ✓ | UTF-16LE (little-endian) |
UTF32 | ✓ | UTF-32 | |
UNICODE | ✓ | ✓ | (JavaScript の文字列。※以下の UNICODE について 参照) |
encoding.js では JavaScript で扱える内部文字コード (JavaScript の文字列) のことを UNICODE
と定義しています。
上記 (特徴) のように、JavaScript の文字列は内部的に UTF-16 コードユニットとして符号化されるため、他の文字コードは正しく扱えません。
そのため、Encoding.convert
によって JavaScript で扱える文字コード配列に変換するには UNICODE
を指定する必要があります。
(※仮にHTMLページが UTF-8 だったとしても JavaScript で扱う場合は UTF8
ではなく UNICODE
を指定します)
Encoding.convert
から返される各文字コード配列の値は UTF8
や SJIS
などの UNICODE
以外を指定した場合は 0-255
までの整数になりますが、 UNICODE
を指定した場合 0-65535
までの整数 (String.prototype.charCodeAt()
の値の範囲 = Code Unit) になります。
JavaScript の文字列 (UNICODE
) から SJIS
に文字コードを変換する:
const unicodeArray = Encoding.stringToCode('こんにちは'); // 文字列から文字コード値の配列に変換
const sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE'
});
console.log(sjisArray);
// [130, 177, 130, 241, 130, 201, 130, 191, 130, 205] (SJISの 'こんにちは' の配列)
SJIS
から UNICODE
に文字コードを変換する:
const sjisArray = [
130, 177, 130, 241, 130, 201, 130, 191, 130, 205
]; // SJISで'こんにちは'の配列
const unicodeArray = Encoding.convert(sjisArray, {
to: 'UNICODE',
from: 'SJIS'
});
const str = Encoding.codeToString(unicodeArray); // 文字コード値の配列から文字列に変換
console.log(str); // 'こんにちは'
文字コードを判定する:
const data = [
227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175
]; // UTF-8で'こんにちは'の配列
const detectedEncoding = Encoding.detect(data);
console.log(`文字コードは${detectedEncoding}`); // '文字コードはUTF8'
(Node.js) SJIS
で書かれたテキストを読み込む例
const fs = require('fs');
const Encoding = require('encoding-japanese');
const sjisBuffer = fs.readFileSync('./sjis.txt');
const unicodeArray = Encoding.convert(sjisBuffer, {
to: 'UNICODE',
from: 'SJIS'
});
console.log(Encoding.codeToString(unicodeArray));
- (Playground) 文字コードの変換や判定を試せるプレイグラウンド
- (Test run) サンプルファイルを読み込み、文字コードを変換するテスト
- (Demo) ファイルを指定して文字コード変換・判定するデモ
指定されたデータの文字コードを判定します。
- data (Array<number>|TypedArray|Buffer|string) : 文字コードを判定する対象の配列または文字列。
- [encodings] (string|Array<string>|Object) : (省略可) 判定を限定する文字コードを文字列または配列で指定します。
省略または
AUTO
を指定すると自動判定になります。SJIS
,UTF8
などの 対応する文字コード に記載されている値を参照してください。
(string|boolean) : 判定された文字コード (SJIS
や UTF8
など「対応する文字コード」のいずれか)、または判定できなかった場合は false
を返します。
引数 encodings
を指定した場合、data
が指定された文字コードに一致すればその文字コード名を返し、そうでなければ false
を返します。
文字コードを判定する例:
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const detectedEncoding = Encoding.detect(sjisArray);
console.log(`文字コードは${detectedEncoding}`); // '文字コードはSJIS'
第二引数 encodings
を使用して判定する文字コードを指定する例。
指定した文字コードが一致する場合はその文字コードを文字列で返し、そうでない場合は false
が返ります:
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const detectedEncoding = Encoding.detect(sjisArray, 'SJIS');
if (detectedEncoding) {
console.log('文字コードはSJISです');
} else {
console.log('SJISとして判定できませんでした');
}
複数の文字コードを指定して判定を限定する例:
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const detectedEncoding = Encoding.detect(sjisArray, ['UTF8', 'SJIS']);
if (detectedEncoding) {
console.log(`文字コードは${detectedEncoding}`); // '文字コードはSJIS'
} else {
console.log('UTF8またはSJISとして判定できませんでした');
}
指定されたデータの文字コードを変換します。
- data (Array<number>|TypedArray|Buffer|string) : 文字コードを変換する対象の配列または文字列。
- to (string|Object) : 変換先の文字コード、またはオブジェクト指定で変換オプション。
SJIS
,UTF8
などの 対応する文字コード に記載されている値を参照してください。 - [from] (string|Array<string>) : (省略可) 変換元の文字コードを文字列または配列で指定します。
省略または
AUTO
を指定すると自動判定になります。
(Array<number>|TypedArray|string) : 変換した文字コードの数値配列を返します。
引数 data
に文字列を渡した場合は、文字列で(変換した文字コードの数値配列を文字列に変換して)返します。
UTF-8 の文字コード配列を Shift_JIS に変換する例:
const utf8Array = [227, 129, 130]; // UTF-8 の「あ」
const sjisArray = Encoding.convert(utf8Array, 'SJIS', 'UTF8');
console.log(sjisArray); // [130, 160] (SJISの「あ」)
Uint8Array
などの TypedArray や、Node.js の Buffer
も同様に扱えます。
const utf8Array = new Uint8Array([227, 129, 130]);
const sjisArray = Encoding.convert(utf8Array, 'SJIS', 'UTF8');
変換元の文字コードを自動判定して変換:
// 引数 from を省略すると文字コードを自動判定します
const utf8Array = [227, 129, 130];
let sjisArray = Encoding.convert(utf8Array, 'SJIS');
// または明示的に 'AUTO' と指定できます
sjisArray = Encoding.convert(utf8Array, 'SJIS', 'AUTO');
第二引数 to
に変換オプションとしてオブジェクトを渡すことで、わかりやすく記述することができます。
また、下記の type
、 fallback
、 bom
などのオプションを指定する際は、オブジェクトでの指定が必要になります。
const utf8Array = [227, 129, 130];
const sjisArray = Encoding.convert(utf8Array, {
to: 'SJIS',
from: 'UTF8'
});
デフォルトでは配列が返りますが、type
オプションの指定で戻り値の型を変えられます。
また、引数 data
が文字列で、 type
オプションが指定されなかった場合は type
= 'string' とみなされます (文字列で返ります)。
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const unicodeString = Encoding.convert(sjisArray, {
to: 'UNICODE',
from: 'SJIS',
type: 'string' // 文字列で返るよう 'string' を指定
});
console.log(unicodeString); // 'おはよ'
以下の type
オプションが指定できます。
- string : 文字列として返ります。
- arraybuffer : ArrayBuffer として (歴史的な理由で実際には
Uint16Array
が) 返ります。 - array : 配列として返ります。 (デフォルト)
type: 'string'
は、配列から文字列に変換する Encoding.codeToString
のショートハンドとして使用することができます。
※ UNICODE
への変換以外は type: 'string'
を指定しても正しく扱えない可能性がありますのでご注意ください
fallback
オプションで、変換先の文字コードで表現できない文字があった場合の扱いを指定できます。
fallback
オプションは以下の値が使用できます。
- html-entity : HTML エンティティ (10進数の HTML 数値文字参照) に置き換える
- html-entity-hex : HTML エンティティ (16進数の HTML 数値文字参照) に置き換える
- ignore : 変換できない文字を無視する
- error : 変換できない文字が含まれている場合にエラーを発生させる
変換先の文字コードで表現できない文字はデフォルトで「?」 (U+003F) に置き換えられますが、
fallback
オプションに html-entity
を指定すると 🍣
等の HTML エンティティに置き換えることができます。
{ fallback: 'html-entity' }
オプションを指定する例:
const unicodeArray = Encoding.stringToCode('寿司🍣ビール🍺');
// fallback指定なし
let sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE'
});
console.log(sjisArray); // '寿司?ビール?' の数値配列に変換されます
// `fallback: html-entity`を指定
sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE',
fallback: 'html-entity'
});
console.log(sjisArray); // '寿司🍣ビール🍺' の数値配列に変換されます
{ fallback: 'html-entity-hex' }
オプションを指定する例:
const unicodeArray = Encoding.stringToCode('ホッケの漢字は𩸽');
const sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE',
fallback: 'html-entity-hex'
});
console.log(sjisArray); // 'ホッケの漢字は𩸽' の数値配列に変換されます
変換先の文字コードで表現できない文字を無視するには、 fallback
オプションに ignore
を指定します。
{ fallback: 'ignore' }
オプションを指定する例:
const unicodeArray = Encoding.stringToCode('寿司🍣ビール🍺');
// fallback指定なし
let sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE'
});
console.log(sjisArray); // '寿司?ビール?' の数値配列に変換されます
// `fallback: ignore`を指定
sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE',
fallback: 'ignore'
});
console.log(sjisArray); // '寿司ビール' の数値配列に変換されます
fallback
オプションに error
を指定すると、変換先の文字コードで表現できない文字が含まれている場合にエラーが発生し、例外が投げられます。
{ fallback: 'error' }
オプションを指定する例:
const unicodeArray = Encoding.stringToCode('おにぎり🍙ラーメン🍜');
try {
const sjisArray = Encoding.convert(unicodeArray, {
to: 'SJIS',
from: 'UNICODE',
fallback: 'error' // 'error'を指定
});
} catch (e) {
console.error(e); // Error: Character cannot be represented: [240, 159, 141, 153]
}
UTF16
に変換する際に bom
オプションを指定すると BOM (byte order mark) の付加を指定できます。
デフォルトは BOM なしになります。
const utf16Array = Encoding.convert(utf8Array, {
to: 'UTF16',
from: 'UTF8',
bom: true // BOMをつける
});
UTF16
のバイトオーダーはデフォルトで big-endian になります。
little-endian として変換したい場合は bom
オプションに LE
を指定します。
const utf16leArray = Encoding.convert(utf8Array, {
to: 'UTF16',
from: 'UTF8',
bom: 'LE' // BOM (little-endian) をつける
});
BOM が不要な場合は UTF16BE
または UTF16LE
を指定することができます。
UTF16BE
は、上位バイトが先頭側になるように並べる方式 (big-endian) で、
UTF16LE
は上位バイトが末尾側になるように並べる方式 (little-endian) になり、どちらも BOM は付きません。
const utf16beArray = Encoding.convert(utf8Array, {
to: 'UTF16BE',
from: 'UTF8'
});
文字コードの数値配列を URI 構成要素としてエンコード(パーセントエンコーディング)された %xx
形式の文字列に変換します。
urlEncode は encodeURIComponent()
と同じく、
下記を除くすべての文字をエスケープします。
エスケープされないもの:
A-Z a-z 0-9 - _ . ! ~ * ' ( )
- data (Array<number>|TypedArray|Buffer|string) : エンコードする対象の配列または文字列。
(string) : URI 構成要素としてエンコードされた (%xx
形式) の文字列が返ります。
Shift_JIS の配列を URL エンコードする例:
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const encodedStr = Encoding.urlEncode(sjisArray);
console.log(encodedStr); // '%82%A8%82%CD%82%E6'
%xx
形式のパーセントエンコーディングされた文字列(URI 構成要素としてエンコードされた文字列)を文字コードの数値配列にデコードします。
- string (string) : デコードする対象の文字列。
(Array<number>) : デコードされた文字コードの数値配列が返ります。
URL エンコードされた Shift_JIS の文字列をデコードする例:
const encodedStr = '%82%A8%82%CD%82%E6'; // 'おはよ' が SJIS で URL エンコードされたもの
const sjisArray = Encoding.urlDecode(encodedStr);
console.log(sjisArray); // [130, 168, 130, 205, 130, 230]
文字コードの数値配列を Base64 エンコードされた文字列に変換します。
- data (Array<number>|TypedArray|Buffer|string) : Base64 エンコードする対象の配列または文字列。
(string) : Base64 エンコードされた文字列が返ります。
Shift_JIS の配列を Base64 エンコードする例:
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const encodedStr = Encoding.base64Encode(sjisArray);
console.log(encodedStr); // 'gqiCzYLm'
Base64 エンコードされた文字列を文字コードの数値配列に変換します。
- string (string) : Base64 エンコードされた文字列。
(Array<number>) : Base64 デコードした文字コードの数値配列が返ります。
base64Encode
と base64Decode
の例:
const sjisArray = [130, 177, 130, 241, 130, 201, 130, 191, 130, 205]; // SJISの「こんにちは」
const encodedStr = Encoding.base64Encode(sjisArray);
console.log(encodedStr); // 'grGC8YLJgr+CzQ=='
const decodedArray = Encoding.base64Decode(encodedStr);
console.log(decodedArray); // [130, 177, 130, 241, 130, 201, 130, 191, 130, 205]
文字コードの数値配列を文字列に変換します。
- code (Array<number>|TypedArray|Buffer) : 文字列に変換する対象の文字コード配列。
(string) : 変換した文字列が返ります。
文字コードの数値配列を文字列に変換する例:
const sjisArray = [130, 168, 130, 205, 130, 230]; // SJISで「おはよ」の配列
const unicodeArray = Encoding.convert(sjisArray, {
to: 'UNICODE',
from: 'SJIS'
});
const unicodeStr = Encoding.codeToString(unicodeArray);
console.log(unicodeStr); // 'おはよ'
文字列を文字コードの数値配列に変換します。
- string (string) : 変換する対象の文字列。
(Array<number>) : 変換した文字コードの数値配列が返ります。
文字列を文字コードの数値配列に変換する例:
const unicodeArray = Encoding.stringToCode('おはよ');
console.log(unicodeArray); // [12362, 12399, 12424]
以下のメソッドは、日本語の全角・半角文字を変換します。
UNICODE
の文字列または UNICODE
の文字コードの数値配列に対して使用できます。
入力されたデータが文字列の場合、変換した文字列を返します。 数値配列の場合、変換した文字コードの数値配列を返します。
- Encoding.toHankakuCase (data) : 全角英数記号文字を半角英数記号文字に変換します。
- Encoding.toZenkakuCase (data) : 半角英数記号文字を全角英数記号文字に変換します。
- Encoding.toHiraganaCase (data) : 全角カタカナを全角ひらがなに変換します。
- Encoding.toKatakanaCase (data) : 全角ひらがなを全角カタカナに変換します。
- Encoding.toHankanaCase (data) : 全角カタカナを半角カタカナに変換します。
- Encoding.toZenkanaCase (data) : 半角カタカナを全角カタカナに変換します。
- Encoding.toHankakuSpace (data) : 全角スペース(U+3000)を半角スペース(U+0020)に変換します。
- Encoding.toZenkakuSpace (data) : 半角スペース(U+0020)を全角スペース(U+3000)に変換します。
- data (Array<number>|TypedArray|Buffer|string) : 変換する対象の文字列または文字コードの数値配列。
(Array<number>|string) : 変換した文字列または文字コードの数値配列が返ります。
全角・半角の文字列を変換する例:
console.log(Encoding.toHankakuCase('abcDEF123@!#*=')); // 'abcDEF123@!#*='
console.log(Encoding.toZenkakuCase('abcDEF123@!#*=')); // 'abcDEF123@!#*='
console.log(Encoding.toHiraganaCase('アイウエオァィゥェォヴボポ')); // 'あいうえおぁぃぅぇぉゔぼぽ'
console.log(Encoding.toKatakanaCase('あいうえおぁぃぅぇぉゔぼぽ')); // 'アイウエオァィゥェォヴボポ'
console.log(Encoding.toHankanaCase('アイウエオァィゥェォヴボポ')); // 'アイウエオァィゥェォヴボポ'
console.log(Encoding.toZenkanaCase('アイウエオァィゥェォヴボポ')); // 'アイウエオァィゥェォヴボポ'
console.log(Encoding.toHankakuSpace('あいうえお abc 123')); // 'あいうえお abc 123'
console.log(Encoding.toZenkakuSpace('あいうえお abc 123')); // 'あいうえお abc 123'
全角・半角の数値配列を変換する例:
const unicodeArray = Encoding.stringToCode('abc123!# あいうアイウ ABCアイウ');
console.log(Encoding.codeToString(Encoding.toHankakuCase(unicodeArray)));
// 'abc123!# あいうアイウ ABCアイウ'
console.log(Encoding.codeToString(Encoding.toZenkakuCase(unicodeArray)));
// 'abc123!# あいうアイウ ABCアイウ'
console.log(Encoding.codeToString(Encoding.toHiraganaCase(unicodeArray)));
// 'abc123!# あいうあいう ABCアイウ'
console.log(Encoding.codeToString(Encoding.toKatakanaCase(unicodeArray)));
// 'abc123!# アイウアイウ ABCアイウ'
console.log(Encoding.codeToString(Encoding.toHankanaCase(unicodeArray)));
// 'abc123!# あいうアイウ ABCアイウ'
console.log(Encoding.codeToString(Encoding.toZenkanaCase(unicodeArray)));
// 'abc123!# あいうアイウ ABCアイウ'
console.log(Encoding.codeToString(Encoding.toHankakuSpace(unicodeArray)));
// 'abc123!# あいうアイウ ABCアイウ'
console.log(Encoding.codeToString(Encoding.toZenkakuSpace(unicodeArray)));
// 'abc123!# あいうアイウ ABCアイウ'
この例では Shift_JIS で書かれたテキストファイルをバイナリデータとして読み込み、
Encoding.convert によって UNICODE
に変換して表示します。
(async () => {
try {
const response = await fetch('shift_jis.txt');
const buffer = await response.arrayBuffer();
// ファイルから読み込んだSJISの文字コード配列
const sjisArray = new Uint8Array(buffer);
// SJISからUNICODE(JavaScriptコードユニット)に文字コードを変換
const unicodeArray = Encoding.convert(sjisArray, {
to: 'UNICODE',
from: 'SJIS'
});
// 表示用に文字コード配列を文字列に変換
const unicodeString = Encoding.codeToString(unicodeArray);
console.log(unicodeString);
} catch (error) {
console.error('Error loading the file:', error);
}
})();
この例の XMLHttpRequest を使ったバージョン
const req = new XMLHttpRequest();
req.open('GET', 'shift_jis.txt', true);
req.responseType = 'arraybuffer';
req.onload = (event) => {
const buffer = req.response;
if (buffer) {
// ファイルから読み込んだSJISの文字コード配列
const sjisArray = new Uint8Array(buffer);
// SJISからUNICODE(JavaScriptコードユニット)に文字コードを変換
const unicodeArray = Encoding.convert(sjisArray, {
to: 'UNICODE',
from: 'SJIS'
});
// 表示用に文字コード配列を文字列に変換
const unicodeString = Encoding.codeToString(unicodeArray);
console.log(unicodeString);
}
};
req.send(null);
この例では、File API を使って選択されたファイルの内容を読み込みます。その際にファイルの文字コードを判定し、
Shift_JIS
や EUC-JP
などで書かれたファイルも文字化けなく表示されるように UNICODE
に変換して表示します。
<input type="file" id="file">
<div id="encoding"></div>
<textarea id="content" rows="5" cols="80"></textarea>
<script>
function onFileSelect(event) {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = function(e) {
const codes = new Uint8Array(e.target.result);
const detectedEncoding = Encoding.detect(codes);
const encoding = document.getElementById('encoding');
encoding.textContent = `Detected encoding: ${detectedEncoding}`;
// UNICODE(JavaScriptコードユニット)に文字コードを変換
const unicodeString = Encoding.convert(codes, {
to: 'UNICODE',
from: detectedEncoding,
type: 'string'
});
document.getElementById('content').value = unicodeString;
};
reader.readAsArrayBuffer(file);
}
document.getElementById('file').addEventListener('change', onFileSelect);
</script>
Pull requests や Issues を歓迎しています。 バグ報告や機能要望などは GitHub の Issues をご利用ください。
Pull requests をする前に、 npm run test
を実行してエラーがないことをご確認ください。
このプロジェクトは MIT ライセンスです。 詳しくは LICENSE ファイルを参照してください。