在JavaScript中将字符转换为ASCII码

1228

如何使用JavaScript将字符转换为其ASCII码?

例如:

从“\n”获取10。


24
请注意,大多数答案中建议使用的String.prototype.charCodeAt() 方法将返回UTF-16代码单元(甚至不是完整的UTF-16编码,这是由于历史原因)。只有前128个Unicode编码点是ASCII字符编码的直接匹配。 - Álvaro González
@ÁlvaroGonzález 这是一个重要的警告。我该如何获取ASCII码,例如对于,获取128 - simlev
5
@simlev所说的是ASCII并没有符号,因为它是在货币符号出现几十年前创建的。在Windows-1252编码中,128代表了这个符号。但是,在随意转换编码时会遇到问题。请注意保持原意。 - Álvaro González
18个回答

1797
"\n".charCodeAt(0);

这里是 charCodeAt 的文档:

charCodeAt() 方法返回一个介于 0 和 65535 之间的整数,表示给定索引处的 UTF-16 代码单元。

UTF-16 代码单元匹配可以用单个 UTF-16 代码单元表示的代码点的 Unicode 代码点。如果 Unicode 代码点不能用单个 UTF-16 代码单元表示(因为其值大于 0xFFFF),则返回的代码单元将是代码点的代理对的第一部分。如果你想要整个代码点值,请使用 codePointAt()

如果你需要支持非 BMP 的 Unicode 字符,如 U+1F602,则不要使用 charCodeAt,因为它将不会返回 128514(或十六进制中的 0x1f602),而是会给出你意料之外的结果:

console.log("\u{1f602}".charCodeAt(0));
// prints 55357 , which is 0xd83d in hexadecimal


806
这的相反是 String.fromCharCode(10) - viam0Zah
226
有趣的事实:你其实不需要 0(第一个参数的值)——只需使用 "\n".charCodeAt() 就可以了。 - Mathias Bynens
14
请注意,与String.fromCharCode( asciiNumVal )不同,stringInstance.charCodeAt( index )并不是String类的静态方法。 - bobobobo
29
@Mathias Bynens,它确实默认为零,但我只是出于兴趣进行了一项性能测试,并且相对于使用0时表现相对较差。http://jsperf.com/default-to-0-vs-0/4** 这只是一个相对的差异,无论如何它非常非常快。 - wade montague
显示剩余8条评论

493

String.prototype.charCodeAt() 可以将字符串字符转换为 ASCII 码。例如:

"ABC".charCodeAt(0) // returns 65

如果需要将数字转换为对应的ASCII字符,请使用String.fromCharCode(10)方法。该方法可以接受多个数字并将它们连接起来,最终返回一个字符串。例如:

String.fromCharCode(65,66,67); // returns 'ABC'

这里是快速ASCII字符参考:

{
"31": "",      "32": " ",     "33": "!",     "34": "\"",    "35": "#",    
"36": "$",     "37": "%",     "38": "&",     "39": "'",     "40": "(",    
"41": ")",     "42": "*",     "43": "+",     "44": ",",     "45": "-",    
"46": ".",     "47": "/",     "48": "0",     "49": "1",     "50": "2",    
"51": "3",     "52": "4",     "53": "5",     "54": "6",     "55": "7",    
"56": "8",     "57": "9",     "58": ":",     "59": ";",     "60": "<",    
"61": "=",     "62": ">",     "63": "?",     "64": "@",     "65": "A",    
"66": "B",     "67": "C",     "68": "D",     "69": "E",     "70": "F",    
"71": "G",     "72": "H",     "73": "I",     "74": "J",     "75": "K",    
"76": "L",     "77": "M",     "78": "N",     "79": "O",     "80": "P",    
"81": "Q",     "82": "R",     "83": "S",     "84": "T",     "85": "U",    
"86": "V",     "87": "W",     "88": "X",     "89": "Y",     "90": "Z",    
"91": "[",     "92": "\\",    "93": "]",     "94": "^",     "95": "_",    
"96": "`",     "97": "a",     "98": "b",     "99": "c",     "100": "d",    
"101": "e",    "102": "f",    "103": "g",    "104": "h",    "105": "i",    
"106": "j",    "107": "k",    "108": "l",    "109": "m",    "110": "n",    
"111": "o",    "112": "p",    "113": "q",    "114": "r",    "115": "s",    
"116": "t",    "117": "u",    "118": "v",    "119": "w",    "120": "x",    
"121": "y",    "122": "z",    "123": "{",    "124": "|",    "125": "}",    
"126": "~",    "127": ""
}

46
更好的 ASCII 参考资料: http://en.wikipedia.org/wiki/ASCII - 我对该页面上表格的着色感到非常自豪,这些着色在近10年来一直保留着 :) - B T
9
@theGrayFox 在命令行输入C:\> man ascii时出现了“Bad command or file name”的错误提示。需要翻译成中文。 - Déjà vu
3
请注意,这些方法是UTF-16兼容的,这意味着根据输入字符串,charCodeAt可以扩展到远远超过1个字节的ASCII值0-127。如果JavaScript正在接受和处理任意字符串输入,请不要假定它在该范围内。 - theferrit32
1
亲爱的开发者,你使用了错误的操作系统。man是一个Linux命令。不确定在Windows上的等效命令是什么。建议在浏览器中使用搜索引擎搜索“man ascii”以获取更安全的结果,这里有一个链接 -> https://man7.org/linux/man-pages/man7/ascii.7.html - tgkprog

64
如果您只有一个字符而不是字符串,您可以使用:
'\n'.charCodeAt();
'\n'.codePointAt();

省略0...

之前比'n'.charCodeAt(0)慢很多,但现在我测试了一下,不再看到差异了(执行了100亿次,包括和不包括0)。仅在Chrome和Firefox中测试性能。


13
这实际上需要更长的时间。只使用零会更快。(在我的电脑上,通过几万次迭代,它花费的时间是两倍左右——使用零需要0.055秒,而非零需要0.126秒) - royhowie

33

虽然其他答案也是正确的,但我更喜欢这种方式:

function ascii (a) { return a.charCodeAt(0); }

然后,要使用它,只需:

var lineBreak = ascii("\n");

我正在使用这个小型快捷方式系统:

$(window).keypress(function(event) {
  if (event.ctrlKey && event.which == ascii("s")) {
    savecontent();
    }
  // ...
  });

你甚至可以在map()或其他方法中使用它:

var ints = 'ergtrer'.split('').map(ascii);

3
只是为了美观,一个新的ES6写法如下:const ascii = a => a.charCodeAt(0); (这段代码的作用是将字符转换成对应的ASCII码值) - axkibe

30

如果想要得到一个字符串中所有ASCII码的总和:

'Foobar'
  .split('')
  .map(char => char.charCodeAt(0))
  .reduce((current, previous) => previous + current)

或者,ES6:

[...'Foobar']
  .map(char => char.charCodeAt(0))
  .reduce((current, previous) => previous + current)

1
请仔细检查你的最后一行。 - Ypnypn
优雅!作为一个函数: function ascii(str) { return str .split('') .map(function (char) { return char + ":" + String(char.charCodeAt(0)) + "\n"; }) .reduce(function (current, previous) { return current + previous; }); } - Darren Griffith
3
[...'Foobar'].reduce((i,s)=>s.charCodeAt(0)+i,0) - ShintoTuna

13

将字符串转换为 UTF-8 数组(流):

const str_to_arr_of_UTF8 = new TextEncoder().encode("Adfgdfs");
// [65, 100, 102, 103, 100, 102, 115]

注意:ASCII 是 UTF-8 的子集,因此这是一种通用的解决方案。


13

为确保完全支持Unicode并具备可逆性,请考虑使用:

'\n'.codePointAt(0);

这将确保在测试超过UTF-16限制的字符时,您将获得其真实的码点值。

例如:

''.codePointAt(0); // 68181
String.fromCodePoint(68181); // ''

''.charCodeAt(0);  // 55298
String.fromCharCode(55298);  // '�'

将特殊字符转换为十六进制表示法可能也很有用,因为一些文本编辑器直接处理这样的字符可能无法正常工作。例如:alert(str.hexEncode().hexDecode()); - Jose Tepedino

11

JavaScript将字符串存储为UTF-16(双字节),因此如果您想忽略第二个字节,只需使用双重位&运算符在0000000011111111(即255)上进行剥离:


JavaScript存储字符串为UTF-16(双字节),如需忽略第二个字节,请使用双重位&运算符对0000000011111111(即255)进行剥离。
'a'.charCodeAt(0) & 255 === 97; // because 'a' = 97 0 
'b'.charCodeAt(0) & 255 === 98; // because 'b' = 98 0 
'✓'.charCodeAt(0) & 255 === 19; // because '✓' = 19 39

为什么你想要忽略第二个字节? - Roberg
3
问题是询问如何从UTF-16字符串(双字节)生成ASCII。如果您未忽略第二个字节,迟早会得到非ASCII代码。 - Steven de Salas
2
@Steven de Salas - 你的“解决方案”是返回错误的 ASCII 代码来获取非 ASCII 字符的非 ASCII 代码吗? - Carl Smith
@CarlSmith,不是错误的选择。只需去除字符的非ASCII组件即可。如果您正在使用单个字节,则这很有用。但是,您的项目可能需要不同的解决方案。 - Steven de Salas

5

截至2023年

从字符到ASCII码

使用方法 charCodeAt

console.log("\n".charCodeAt())

从ASCII码到字符

使用方法 fromCharCode

console.log(String.fromCharCode(10))


1
这不支持非BMP Unicode字符,正如您所期望的那样。 - Flimm
这不是问题的一部分。 - underflow
这个问题是关于如何将一个字符转换为它的 ASCII 码。您的答案只适用于一些字符,而并非所有字符。 - Flimm

4

将字符串转换为累积数字:

const stringToSum = str => [...str||"A"].reduce((a, x) => a += x.codePointAt(0), 0);

console.log(stringToSum("A"));              // 65
console.log(stringToSum("Roko"));           // 411
console.log(stringToSum("Stack Overflow")); // 1386

应用场景:

假设您想根据用户名生成不同的背景颜色:

const stringToSum = str => [...str||"A"].reduce((a, x) => a += x.codePointAt(0), 0);

const UI_userIcon = user => {
  const hue = (stringToSum(user.name) - 65) % 360; // "A" = hue: 0
  console.log(`Hue: ${hue}`);
  return `<div class="UserIcon" style="background:hsl(${hue}, 80%, 60%)" title="${user.name}">
    <span class="UserIcon-letter">${user.name[0].toUpperCase()}</span>
  </div>`;
};

[
  {name:"A"},
  {name:"Amanda"},
  {name:"amanda"},
  {name:"Anna"},
].forEach(user => {
  document.body.insertAdjacentHTML("beforeend", UI_userIcon(user));
});
.UserIcon {
  width: 4em;
  height: 4em;
  border-radius: 4em;
  display: inline-flex;
  justify-content: center;
  align-items: center;
}

.UserIcon-letter {
  font: 700 2em/0 sans-serif;
  color: #fff;
}


为什么是数字“65”?它代表什么? - Reality
“-65”是完全可选的。因为ASCII中“A”字符的数字值为“65”。-65是可选的,用于将第一个(“A”)字符作为int类型的0获取。 - Roko C. Buljan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接