ASCII的长度和优点

本文介绍了ASCII编码的发展历程,包括从Hollerith卡编码到BCDIC再到EBCDIC的变化过程,解释了为什么最终选择了7位编码而非6位或8位。同时,文章还探讨了ASCII编码的优势、扩展ASCII的应用及双字节字符集(DBCS)和Unicode的出现背景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在《Windows程序设计》中有这样一段话:ASCII的开发过程中对于代码的宽度应该是6位、7位或是8位,一直争议不断。考虑到可靠性,不能使用转换字符。因此ASCII不能使用6位编码。考虑到成本价格,也派出了8位编码的可能性。(位数多在当时是非常昂贵的。)(Charles Petzold著。第五版 2.1.1)

   这句话一直不太理解。上网搜了一下。整理一下。

   一、 ASCII由Hollerith卡的编码演变而来。Hollerith卡的编码变为BCDIC编码(6位),在发展为EBCDIC(8位)。EBCDIC是IBM的大型机标准。

如果使用6位码,那么可以有64个字符,这样就必须使用转换字符进行扩充,例如:在6位编码中,大写字母没有包含进去,我们就定义个转义字符,如\a代表大写字母A,\b代表字母B.也就是用已经分配的编码来组合替代未分配的编码.这样就会产生很多麻烦。尽管我们有些时候(比如C语言)还是使用转义字符。个人认为这是为了使用的方便而不是扩展。

二、随着计算机的发展,8位字节标准的确立,就可以用一个字节来存储ASCII。这样就多出来128个空位。IBM在1981年推出了这样的256个字符的字符集,包含了一些希腊字母以及其他字符。

三、另外,可以让最高位作为奇偶校验位。例如:“F”的ASCII码为46H,采用奇校验方式,为“0100 0110“,而不是“100 0110 ”。

四、ASCII的优点。26个字母代码是连续的(在EBCDIC代码中就不是这样的);大写字母和小写字母可通过翻转一位就可相互转化;10个数位的代码可从数值本身方便地得到(0是30H,9是39H)。

五、扩展至后的ASCII仍然不够用。双字节字符集(DBCS)诞生。例如中文的汉字就占两个字节。这种方式的问题很多。例如一个字符串的长度不是字节长度;如果指针指向了一个字节,那么前一个字节在哪里?

六、还有一些编码方式,都不是很完美。相对较好的方式是Unicode。即宽字符方式。它规定每个字符(不是字节)的长度不是8位,而是16位。中日韩的文字占用从0x3000-0x9FFF的代码。当然这样原来的ASCII字符就会浪费很多空间了。更严重的是,Unicode使用的仍然不多。

<think>好的,我现在要解决用户的问题:如何在JavaScript中计算字符串长度。用户提到他们之前讨论过数字转字符串的方法,现在想了解如何计算字符串长度。根据提供的引用,用户已经给出四个不同的方法,我需要整合这些信息,并结合自己的知识给出清晰的回答。 首先,我需要明确用户的需求。用户可能指的是两种不同的长度:一种是字符数(即字符串的length属性),另一种是字节数(比如中文字符算两个字节)。根据引用中的内容,用户提供的几个方法都是关于计算字节长度的,所以用户可能是在问如何计算字符串的字节长度,特别是处理双字节字符(如中文)的情况。 接下来,我需要回顾提供的引用内容。引用1中的函数calculate_byte似乎通过遍历字符串,检查每个字符的编码,如果超过255则加2字节,否则加1字节。引用2中的方法gblen类似,但判断条件是charCodeAt(i) > 127或等于94,这种情况下加2字节。引用3中的方法使用正则替换非单字节字符为"ay",然后取长度。引用4中的两个方法,一个类似引用1,另一个先取字符串长度,再遇到超过255的字符时加1,总结果相当于字符数加上双字节字符的数量。 我需要比较这些方法的异同,并解释它们的原理。例如,ASCII字符通常是单字节(0-127或0-255),而中文等Unicode字符可能是双字节或更多。但实际在JavaScript中,字符串是基于UTF-16的,每个字符占用2字节,但用户可能关心的是存储或传输时的字节长度,比如UTF-8编码下中文字符占3字节。不过根据引用中的方法,似乎都是简单地将双字节字符算作2字节,这可能适用于某些特定场景,如旧版的编码方式(GBK等)。 需要指出这些方法的局限性,比如它们可能不准确,因为现代编码如UTF-8中,字符可能占用1-4字节。但用户提供的例子都是基于charCodeAt来判断,这可能适用于处理特定编码的情况,比如GB2312或GBK,其中中文字符确实占两个字节。 然后,我需要组织回答的结构,先介绍基本的length属性,说明其返回字符数。然后介绍计算字节长度的方法,引用中的不同实现方式。可能需要推荐几种方法,并比较它们的优缺点。例如,正则替换法简洁,但可能效率不如循环;循环遍历法更灵活,可以处理不同情况。 另外,需要注意用户可能混淆字符长度字节长度,因此需要明确区分这两个概念。如果用户需要的是字符数,直接使用length即可;如果需要字节数(如处理后端数据库字段长度限制),则需要用其他方法。 还需要考虑特殊字符,比如Unicode扩展区的字符,比如emoji,可能charCodeAt返回的值是否超过255或127,这时候可能需要更复杂的判断。例如,一些emoji是代理对,即两个16位码元组成的,这时候charCodeAt可能无法准确判断,需要检查代码点是否超过0xFFFF。但引用中的方法可能没有处理这种情况,所以需要指出这些方法的局限性。 最后,给出推荐的方法,并附上代码示例,说明如何实现。可能还需要提到现代浏览器中的API,如TextEncoder,可以更准确地计算UTF-8字节长度,但兼容性问题需要注意。不过用户提供的引用中没有提到这个,所以可能需要作为补充内容。 总结步骤: 1. 区分字符长度字节长度。 2. 介绍字符串的length属性。 3. 讨论字节长度的计算方法,引用提供的几种方法。 4. 分析不同方法的原理适用场景。 5. 指出潜在问题局限性。 6. 推荐方法并给出示例。 7. 可能提到TextEncoder作为更准确的方法。</think>在JavaScript中计算字符串长度需区分 **字符数量** **字节长度**,以下是具体方法及适用场景: --- ### 一、基础字符数量 直接使用字符串的 `length` 属性获取字符数量: ```javascript const str = "Hello 世界"; console.log(str.length); // 输出:8(含空格) ``` --- ### 二、字节长度计算(含双字节字符) 适用于中文等双字节字符场景,以下是常见方法: #### 1. 遍历字符法(推荐) 通过 `charCodeAt()` 判断字符编码,中文等Unicode字符编码大于255时按双字节计算: ```javascript function getByteLength(str) { let bytes = 0; for (let i = 0; i < str.length; i++) { const code = str.charCodeAt(i); bytes += code > 255 ? 2 : 1; // 根据编码范围判断字节 } return bytes; } console.log(getByteLength("abc测试")); // 输出:7 (a,b,c=1字节×3,测、试=2字节×2) ``` #### 2. 正则替换法 用正则将双字节字符替换为特定标记后计算长度: ```javascript function getByteLength(str) { return str.replace(/[^\x00-\xff]/g, "**").length; } console.log(getByteLength("123中国")); // 输出:7("123**中国" → 长度7) ``` #### 3. 原型扩展法 扩展字符串原型方法(需谨慎使用): ```javascript String.prototype.getBytes = function() { return this.replace(/[^\x00-\xff]/g, "aa").length; }; console.log("测试".getBytes()); // 输出:4 ``` --- ### 三、现代API方法(UTF-8编码) 通过 `TextEncoder` 准确计算UTF-8字节长度(需浏览器支持): ```javascript function getUtf8Bytes(str) { return new TextEncoder().encode(str).length; } console.log(getUtf8Bytes("🔥")); // 输出:4(Emoji占4字节) ``` --- ### 四、方法对比与建议 | 方法 | 优点 | 缺点 | 适用场景 | |---------------|------------------------|----------------------------|------------------------| | `length` | 简单快速 | 不区分单/双字节 | 纯ASCII字符计数 | | 遍历字符法 | 灵活可控 | 循环性能消耗 | 需兼容旧浏览器的场景 | | 正则替换法 | 代码简洁 | 可能误判复杂Unicode字符 | 简单双字节计算 | | `TextEncoder` | 精确支持UTF-8多字节 | 不兼容IE及旧移动端浏览器 | 现代Web应用 | --- ### 五、常见问题解答 1. **为什么中文字符有时算2字节,有时算3字节?** 不同编码标准导致差异:GBK编码中中文占2字节,UTF-8编码占3字节[^1]。 2. **如何处理Emoji等复杂字符?** 优先使用 `TextEncoder`,能正确处理代理对(如 `"\ud83d\udd25"` 表示🔥)[^2]。 3. **为何不推荐修改String原型?** 原型扩展可能导致命名冲突,建议封装为独立函数[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值