【JavaScript】ASCIIコードを文字列に変換する方法|fromCharCode・charCodeAt・暗号実装まで完全解説

JavaScriptでASCIIコードを文字列に変換するには、String.fromCharCode() メソッドを使います。逆に文字からASCIIコードを取得するには charCodeAt() を使います。

この記事では、ASCIIコードの基本概念から String.fromCharCode() の使い方、コード表、大文字⇔小文字変換、ROT13暗号・シーザー暗号の実装、実務でのバリデーション活用、Unicode との関係まで体系的に解説します。

スポンサーリンク

ASCIIコードとは

ASCII(American Standard Code for Information Interchange)は、英数字・記号・制御文字を0〜127の数値にマッピングした文字コード体系です。1963年に策定され、現在のUnicodeでも最初の128文字はASCIIと完全に互換性があります。

ASCIIコードの特徴

  • 0〜31:制御文字(改行、タブなど)
  • 32〜126:印字可能文字(英字、数字、記号)
  • 127:DEL(削除)
  • 48〜57:数字 0〜9
  • 65〜90:大文字 A〜Z
  • 97〜122:小文字 a〜z

String.fromCharCode() の基本

String.fromCharCode() は、指定したASCIIコード(Unicode値)に対応する文字列を返す静的メソッドです。

基本構文

構文
String.fromCharCode(num1)
String.fromCharCode(num1, num2)
String.fromCharCode(num1, num2, ..., numN)

基本的な使い方

JavaScript
// ASCIIコード 65 → 文字 'A'
const char = String.fromCharCode(65);
console.log(char);  // "A"

// 小文字 a のASCIIコードは 97
console.log(String.fromCharCode(97));   // "a"

// 数字 0 のASCIIコードは 48
console.log(String.fromCharCode(48));   // "0"

// スペースのASCIIコードは 32
console.log(String.fromCharCode(32));   // " "

実行結果

A
a
0
 

複数のASCIIコードをまとめて変換

String.fromCharCode()複数の引数を受け取り、それぞれに対応する文字を連結した文字列を返します。

JavaScript
// 複数のASCIIコードをまとめて変換
const hello = String.fromCharCode(72, 101, 108, 108, 111);
console.log(hello);  // "Hello"

// 配列のASCIIコードをスプレッド構文で変換
const codes = [74, 83];
console.log(String.fromCharCode(...codes));  // "JS"

// 配列を map + fromCharCode で変換する方法
const asciiCodes = [87, 111, 114, 108, 100];
const result = asciiCodes.map(code => String.fromCharCode(code)).join('');
console.log(result);  // "World"

実行結果

Hello
JS
World

ポイント:配列をまとめて変換するには、スプレッド構文 String.fromCharCode(...codes) が最もシンプルです。

文字 → ASCIIコード(charCodeAt)

fromCharCode() の逆変換として、文字からASCIIコードを取得するには charCodeAt() メソッドを使います。

JavaScript
// 文字 → ASCIIコード
console.log('A'.charCodeAt(0));  // 65
console.log('a'.charCodeAt(0));  // 97
console.log('0'.charCodeAt(0));  // 48
console.log(' '.charCodeAt(0));  // 32

// 相互変換の確認
const code = 'Z'.charCodeAt(0);        // 90
const char = String.fromCharCode(code);  // "Z"
console.log(code, char);                // 90 "Z"

実行結果

65
97
48
32
90 "Z"

文字列全体をASCIIコード配列に変換

JavaScript
// 文字列 → ASCIIコード配列
const str = 'Hello';
const codes = [...str].map(c => c.charCodeAt(0));
console.log(codes);  // [72, 101, 108, 108, 111]

// ASCIIコード配列 → 文字列に復元
const restored = String.fromCharCode(...codes);
console.log(restored);  // "Hello"

実行結果

[72, 101, 108, 108, 111]
Hello

ASCIIコード表(主要な印字可能文字)

ASCIIの印字可能文字(コード32〜126)の中から、特に使用頻度の高い範囲を一覧表にまとめます。

数字(48〜57)

コード 文字 コード 文字 コード 文字
480491502
513524535
546557568
579

大文字アルファベット(65〜90)

コード 文字 コード 文字 コード 文字 コード 文字
65A66B67C68D
69E70F71G72H
73I74J75K76L
77M78N79O80P
81Q82R83S84T
85U86V87W88X
89Y90Z

小文字アルファベット(97〜122)

コード 文字 コード 文字 コード 文字 コード 文字
97a98b99c100d
101e102f103g104h
105i106j107k108l
109m110n111o112p
113q114r115s116t
117u118v119w120x
121y122z

主要な記号・特殊文字

コード 文字 名称 コード 文字 名称
32(空白)スペース33!感嘆符
34ダブルクォート39シングルクォート
40(左括弧41)右括弧
43+プラス45ハイフン
46.ピリオド47/スラッシュ
58:コロン59;セミコロン
61=等号64@アットマーク
91[左角括弧93]右角括弧
123{左波括弧125}右波括弧

大文字 ⇔ 小文字変換(ASCIIコード演算)

ASCIIコードでは、大文字と小文字の差は常に32です。この性質を利用して、コード演算による大文字⇔小文字変換ができます。

大文字と小文字のASCIIコード関係

  • 大文字 A(65)→ 小文字 a(97):差は 32
  • 大文字 Z(90)→ 小文字 z(122):差は 32
  • 大文字 → 小文字:ASCIIコード + 32
  • 小文字 → 大文字:ASCIIコード - 32
JavaScript
// 大文字 → 小文字(+32)
function toLowerByAscii(char) {
  const code = char.charCodeAt(0);
  if (code >= 65 && code <= 90) {
    return String.fromCharCode(code + 32);
  }
  return char;
}

// 小文字 → 大文字(-32)
function toUpperByAscii(char) {
  const code = char.charCodeAt(0);
  if (code >= 97 && code <= 122) {
    return String.fromCharCode(code - 32);
  }
  return char;
}

console.log(toLowerByAscii('A'));  // "a"
console.log(toLowerByAscii('Z'));  // "z"
console.log(toUpperByAscii('a'));  // "A"
console.log(toUpperByAscii('z'));  // "Z"

実行結果

a
z
A
Z

文字列全体を変換する関数

JavaScript
// 文字列全体を小文字に変換(ASCII演算版)
function toLowerCaseAscii(str) {
  let result = '';
  for (let i = 0; i < str.length; i++) {
    const code = str.charCodeAt(i);
    if (code >= 65 && code <= 90) {
      result += String.fromCharCode(code + 32);
    } else {
      result += str[i];
    }
  }
  return result;
}

console.log(toLowerCaseAscii('Hello World'));  // "hello world"
console.log(toLowerCaseAscii('JavaScript'));   // "javascript"

実行結果

hello world
javascript

注意:実務では toLowerCase() / toUpperCase() を使うのが一般的です。ASCIIコード演算による変換は、暗号処理やアルゴリズム学習での理解に役立ちます。

ROT13暗号の実装

ROT13は、アルファベットを13文字ずらす暗号方式です。26文字のちょうど半分をずらすため、暗号化と復号化が同じ処理になるという特徴があります。

JavaScript
function rot13(str) {
  let result = '';
  for (let i = 0; i < str.length; i++) {
    const code = str.charCodeAt(i);

    if (code >= 65 && code <= 90) {
      // 大文字: A(65)〜Z(90)
      result += String.fromCharCode((code - 65 + 13) % 26 + 65);
    } else if (code >= 97 && code <= 122) {
      // 小文字: a(97)〜z(122)
      result += String.fromCharCode((code - 97 + 13) % 26 + 97);
    } else {
      // アルファベット以外はそのまま
      result += str[i];
    }
  }
  return result;
}

// 暗号化
const encrypted = rot13('Hello, World!');
console.log(encrypted);  // "Uryyb, Jbeyq!"

// 復号化(同じ関数を適用)
const decrypted = rot13(encrypted);
console.log(decrypted);  // "Hello, World!"

実行結果

Uryyb, Jbeyq!
Hello, World!

ポイント:ROT13は (code - base + 13) % 26 + base という計算式で実装します。% 26 で Z の先に戻るよう巡回させるのがコツです。

シーザー暗号の実装

シーザー暗号は、アルファベットを任意の数だけずらす暗号方式です。ROT13はシーザー暗号のシフト量13版といえます。

JavaScript
// シーザー暗号:任意のシフト量で暗号化
function caesarCipher(str, shift) {
  // 負のシフトにも対応(mod演算で正規化)
  const normalizedShift = ((shift % 26) + 26) % 26;
  let result = '';

  for (let i = 0; i < str.length; i++) {
    const code = str.charCodeAt(i);

    if (code >= 65 && code <= 90) {
      result += String.fromCharCode((code - 65 + normalizedShift) % 26 + 65);
    } else if (code >= 97 && code <= 122) {
      result += String.fromCharCode((code - 97 + normalizedShift) % 26 + 97);
    } else {
      result += str[i];
    }
  }
  return result;
}

// シフト量 3 で暗号化
console.log(caesarCipher('ABC xyz', 3));    // "DEF abc"

// シフト量 -3 で復号化
console.log(caesarCipher('DEF abc', -3));   // "ABC xyz"

// シフト量 13 = ROT13 と同じ
console.log(caesarCipher('Hello', 13));    // "Uryyb"

実行結果

DEF abc
ABC xyz
Uryyb

アルファベット一覧の生成

ASCIIコードの連番性を利用すれば、アルファベット一覧を動的に生成できます。

JavaScript
// 大文字アルファベット A〜Z を生成
const upperAlphabet = Array.from(
  { length: 26 },
  (_, i) => String.fromCharCode(65 + i)
);
console.log(upperAlphabet.join(' '));
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

// 小文字アルファベット a〜z を生成
const lowerAlphabet = Array.from(
  { length: 26 },
  (_, i) => String.fromCharCode(97 + i)
);
console.log(lowerAlphabet.join(' '));
// a b c d e f g h i j k l m n o p q r s t u v w x y z

// 数字 0〜9 を生成
const digits = Array.from(
  { length: 10 },
  (_, i) => String.fromCharCode(48 + i)
);
console.log(digits.join(' '));
// 0 1 2 3 4 5 6 7 8 9

実行結果

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9

実務での活用例

ASCIIコードによるバリデーション

ASCIIコードの範囲を利用して、文字種を判定するバリデーション関数を実装できます。

JavaScript
// 半角英字のみか判定
function isAlpha(char) {
  const code = char.charCodeAt(0);
  return (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
}

// 半角数字のみか判定
function isDigit(char) {
  const code = char.charCodeAt(0);
  return code >= 48 && code <= 57;
}

// 半角英数字のみか判定
function isAlphaNumeric(char) {
  return isAlpha(char) || isDigit(char);
}

// ASCII印字可能文字か判定(32〜126)
function isPrintableAscii(char) {
  const code = char.charCodeAt(0);
  return code >= 32 && code <= 126;
}

console.log(isAlpha('A'));           // true
console.log(isAlpha('3'));           // false
console.log(isDigit('5'));           // true
console.log(isAlphaNumeric('z'));    // true
console.log(isPrintableAscii('@'));  // true

実行結果

true
false
true
true
true

文字列が半角英数字のみか検証する

JavaScript
// 文字列全体が半角英数字のみかチェック
function isAlphaNumericString(str) {
  for (let i = 0; i < str.length; i++) {
    const code = str.charCodeAt(i);
    const isUpper  = code >= 65 && code <= 90;
    const isLower  = code >= 97 && code <= 122;
    const isNumber = code >= 48 && code <= 57;
    if (!isUpper && !isLower && !isNumber) {
      return false;
    }
  }
  return str.length > 0;
}

console.log(isAlphaNumericString('Hello123'));   // true
console.log(isAlphaNumericString('Hello 123'));  // false(スペースを含む)
console.log(isAlphaNumericString('user@name'));  // false(@を含む)
console.log(isAlphaNumericString(''));           // false(空文字)

実行結果

true
false
false
false

パスワード強度チェック

JavaScript
// ASCIIコードでパスワード文字種を判定
function checkPasswordStrength(password) {
  let hasUpper = false;
  let hasLower = false;
  let hasDigit = false;
  let hasSymbol = false;

  for (let i = 0; i < password.length; i++) {
    const code = password.charCodeAt(i);
    if (code >= 65 && code <= 90)  hasUpper = true;
    else if (code >= 97 && code <= 122) hasLower = true;
    else if (code >= 48 && code <= 57)  hasDigit = true;
    else if (code >= 33 && code <= 126) hasSymbol = true;
  }

  const score = [hasUpper, hasLower, hasDigit, hasSymbol]
    .filter(Boolean).length;

  const levels = ['非常に弱い', '弱い', '普通', '強い', '非常に強い'];
  return {
    score,
    level: levels[score],
    details: { hasUpper, hasLower, hasDigit, hasSymbol }
  };
}

console.log(checkPasswordStrength('password'));
// { score: 1, level: "弱い", details: { ... } }

console.log(checkPasswordStrength('Pass123!'));
// { score: 4, level: "非常に強い", details: { ... } }

実行結果

{ score: 1, level: "弱い", details: { hasUpper: false, hasLower: true, hasDigit: false, hasSymbol: false } }
{ score: 4, level: "非常に強い", details: { hasUpper: true, hasLower: true, hasDigit: true, hasSymbol: true } }

Unicode(fromCodePoint / codePointAt)との関係

ASCIIコード(0〜127)の範囲では fromCharCodefromCodePoint は同じ結果を返します。ただし、65535を超えるUnicodeコードポイント(絵文字やCJK拡張漢字など)を扱う場合は fromCodePoint を使う必要があります。

JavaScript
// ASCII範囲(0〜127):どちらも同じ結果
console.log(String.fromCharCode(65));    // "A"
console.log(String.fromCodePoint(65));   // "A"

// Unicode範囲(65535超):fromCodePointが必要
console.log(String.fromCodePoint(128522));  // "?"
console.log(String.fromCodePoint(128640));  // "?"

// fromCharCodeでは絵文字を正しく生成できない
console.log(String.fromCharCode(128522));  // 文字化け(サロゲートペア非対応)

// 逆変換も同様
console.log('A'.charCodeAt(0));     // 65
console.log('A'.codePointAt(0));    // 65
console.log('?'.codePointAt(0));   // 128522
console.log('?'.charCodeAt(0));    // 55357(サロゲートペアの上位のみ)

fromCharCode と fromCodePoint の使い分け

項目 fromCharCode fromCodePoint
対応範囲0〜65535(UTF-16コード単位)0〜1114111(全Unicodeコードポイント)
ASCII文字対応対応
絵文字・サロゲートペア非対応(文字化け)対応
ECMAScriptES1〜ES2015(ES6)〜
推奨用途ASCII範囲のみの処理絵文字を含む全Unicode処理

ポイント:ASCII範囲(0〜127)の処理には fromCharCode で十分です。絵文字や日本語の特殊文字を扱う場合は fromCodePoint / codePointAt を使いましょう。

ブラウザ互換性

メソッド Chrome Firefox Safari Edge Node.js
String.fromCharCode()1+1+1+12+0.10+
charCodeAt()1+1+1+12+0.10+
String.fromCodePoint()41+29+10+12+4+
codePointAt()41+29+10+12+4+

String.fromCharCode()charCodeAt() はES1から存在する最古のメソッドであり、IE6を含むすべてのブラウザで利用可能です。互換性を心配する必要はありません。

よくある質問(FAQ)

Q. ASCIIコードを文字に変換するにはどうすればよいですか?
A. String.fromCharCode(65)"A"が返ります(65はAのASCIIコード)。複数のコードを一度に変換するにはString.fromCharCode(72, 101, 108, 108, 111)のようにカンマ区切りで渡します。UnicodeのコードポイントにはString.fromCodePoint()を使います。
Q. 文字のASCIIコードを取得するにはどうすればよいですか?
A. "A".charCodeAt(0)で65(AのASCIIコード)が返ります。引数は文字列内のインデックスです。UnicodeのコードポイントはcharCodeAt()で2バイト以上の文字(絵文字等)が正しく取れない場合があります。その場合は"A".codePointAt(0)を使います。
Q. ASCIIコードのアルファベット範囲(大文字・小文字)を判定するにはどうすればよいですか?
A. charCodeAt()で取得したコードを比較します:大文字A-Zは65-90、小文字a-zは97-122の範囲です。例:const code = char.charCodeAt(0); const isUpper = code >= 65 && code <= 90;。JavaScriptの/[A-Z]/.test(char)(正規表現)でもシンプルに判定できます。

まとめ

やりたいこと メソッド・方法 コード例
ASCIIコード→文字String.fromCharCode()String.fromCharCode(65)"A"
文字→ASCIIコードcharCodeAt()'A'.charCodeAt(0)65
複数コードを一括変換fromCharCode(...配列)String.fromCharCode(72,101)"He"
大文字⇔小文字変換ASCIIコード ± 32fromCharCode(code + 32)
ROT13暗号(code - base + 13) % 26rot13('Hello')"Uryyb"
シーザー暗号(code - base + shift) % 26caesarCipher('ABC', 3)"DEF"
アルファベット一覧生成Array.from + fromCharCodeArray.from({length:26},...)
絵文字を含む文字変換fromCodePoint()String.fromCodePoint(128522)"?"

ASCIIコードと文字の相互変換は、バリデーション、暗号処理、文字列生成など多くの場面で活用できます。String.fromCharCode()charCodeAt() のペアをしっかり覚えておけば、文字コードレベルの操作が自在に行えるようになります。

関連記事