你不知道的 maxlength

日常工作中会遇到一些需要考虑最大长度的字段,比如手机号、邮箱地址、姓名、URL等,你是否仔细求证过这些值的字数限制呢?

一、手机号码

手机号码最长多少位?生活常识告诉我们是11位,这个结论放之四海而皆准吗?(美国目前使用的手机号为10位)不妨让我们了解一下相关的背景知识。

我们日常使用的手机号码标准由 ITU-T,也就是国际电信联盟-电信标准化部门(International Telecommunication Union Telecommunication Standardization Sector)制定,对应的标准为 ITU-T 国际 E.164 号码标准,号码由十进制数字组成,ITU-T 建议用于地理区域、全球业务、网络和成组国家的国际号码长度最长15位(不包括国际呼叫字冠)。

注:国际呼叫字冠,也被称为国际字冠、国际前缀或者国际接入码,是拨打国际长途电话时需要输入的号码,如:香港是001,美国是011,中国大陆是00。为方便用户拨号,国际电信联盟的标准规定“+”号做为通用的国际字冠。

1.1 ITU-T 国际 E.164 号码

ITU-T 国际 E.164 号码,主要包括以下几种:

  1. 用于地理区域的 ITU-T 国际 E.164 号码(International ITU-T E.164-number structure for geographic areas)
    • 格式: CC + NDC + SN 最长15位
      • CC 用于地理区域的国家码,1-3位
      • NDC 国内目的地码(可选)
      • SN 用户号码
  2. 用于全球业务的 ITU-T 国际 E.164 号码(International ITU-T E.164-number structure for global services)
    • 格式: CC + GSN 最长15位
      • CC 用于全球业务的国家码,3位
      • GSN 全球用户号码,最长12位
  3. 用于网络的 ITU-T 国际 E.164 号码(International ITU-T E.164-number structure for Networks)
    • 格式: CC + IC + SN 最长15位
      • CC 网络国家码,3位
      • IC 标识码,1-4位
      • SN 用户号码
  4. 用于成组国家的 ITU-T 国际 E.164 号码(International ITU-T E.164-number structure for groups of countries)
    • 格式: CC + GIC + SN 最长15位
      • CC 组成国家的国家码,3位
      • GIC 组标识别,1位
      • SN 用户号码,最长11位
  5. 用于试验的 ITU-T 国际 E.164 号码(International ITU-T E.164-number structure for Trials)
    • 格式: 991 + TIC + SN 最长15位
      • ITC 试验识别码
      • SN 用户号码
相关英语缩写
  • CC Country Code 国家码
  • NDC National Destination Code 国内目的地码
  • SN Subscriber Number 用户号码
  • GSN Global Subscriber Number 全球用户号码
  • IC Identification Code 标识码
  • GIC Group Identification Code 组标识码
  • TIC Trial Identification Code 试验识别码

1.2 国内手机号码

目前国内的手机号码格式为:3位移动接入码+4位地区编码+4位用户编码,总长11位(不包括国际字冠和国家代码); 如果加上中国国家代码,即“86”,总长13位。手机号码 1xx-xxxx-xxxx 加上国际字冠和国家代码后,对应的国际号码为 +86-1xx-xxxx-xxxx0086-1xx-xxxx-xxxx

1.3 总结

当前国内手机号总长11位(不包括国际字冠和国家代码),如果需要考虑国际化则应该参照国际电信联盟的 E.164 号码标准,总长度限制在15位以内(包括国家代码,不包括国际呼叫字冠)。另外国内的物联卡(物联网卡)号段,自2018年起,从11位升级成13位,有别于普通手机号码。

1.4 相关链接

二、身份证号码

我国的公民身份证号码标准为GB11643-1999《公民身份号码》,它是之前GB11643-1989《社会保障号码》的修订版,从1999年7月1日开始实施。 从1999年10月1日起,全国实行公民身份证号码制度,国家为每个公民从出生之日起就编定唯一的、终身不变的身份代码。

目前国内一共存在两代居民身份证:

  1. 第一代居民身份证,从1984年开始颁发,2013年1月1日起停止使用。身份证号码为15位。
  2. 第二代居民身份证,从2004年1月1日开始换发。身份证号码为18位(和第一代15位编码相比,出生年份从2位升成4位,末尾增加一位校验码)。

2.1 第二代居民身份证

第二代公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

各位数字的解释:

  1. 第一、二位表示编码对象常住户口所在省(自治区、直辖市、特别行政区)的行政区划代码。
  2. 第三、四位表示编码对象常住户口所在市(地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码)的行政区划代码。
  3. 第五、六位表示编码对象常住户口所在县(市辖区、县级市、旗)的行政区划代码。
  4. 第七位到第十四位表示编码对象出生的年、月、日,其中年份用四位数字表示。
  5. 第十五位到十七位表示地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
  6. 最后一位为校验码,根据前面十七位数字计算得出,如果计算出的校验码为10,用罗马数字X(大写英文字母)表示。

2.2 总结

目前国内的居民身份号码主流长度为18位(第18位为0-9或X),同时因存在未及时更换第二代居民身份证的情况,部分身份证号码为15位。

2.3 相关链接

三、姓名

这里暂且只讨论中文姓名,目前并没有明确的标准对公民的姓名长度做出限制。在2007年,公安部曾经起草过《姓名登记条例(初稿)》,对汉字姓名的长度做出规定,最长6个汉字,但后来因为争议太大,条例没有正式发布。目前在中国大陆和台湾,最长的汉字姓名为15个字。

3.1 相关新闻

来自北京晚报的新闻:

三字名字占八成以上

公安部全国公民身份证号码查询服务中心昨天发布的一项最新姓名统计显示,全国汉族户籍人口中两字姓名的人数有1.6亿多,占到全国汉族户籍总人口的14.22%。而三字姓名的户籍人口有10亿多,占到全国汉族总人口的85.61%。姓名是4个字及以上的只有197万多人。

汉族姓名最长15个字

据统计,汉族的姓名超过10个字的并不多见,其中最长的姓名达到了15个字。姓名字数在10字以上的有近千人,其中10字姓名者594人,11字姓名者272人,12字姓名者有94人,13字姓名者和14字姓名者分别为33人和5人。据统计,汉族姓名字数10字以上的近千人中,97%都在新疆维吾尔自治区。

条例规定姓名最长可6字

日前由公安部起草完成的《姓名登记条例(初稿)》对姓名长度作出规定,即除使用汉族以外其他民族文字,或者书写、译写汉字者以外,姓名用字应当在二个汉字以上、六个汉字以下。同时规定,姓名不得使用或者含有已简化的繁体字、已淘汰的异体字(姓氏中的异体字除外)、自造字、外国文字、汉语拼音字母、阿拉伯数字、符号和其他超出规范的汉字和少数民族文字范围以外的字样。

来自 ETtoday 的新闻:

立法院修法通過民眾一生可以改名3次,嘉義縣一位多次改名的黃姓男子立刻到戶政所申請,一口氣增加4個字,現在他的身分證姓名欄上寫著「黃宏成台灣阿成世界偉人財神總統」,一共15個字,打破內政部公布姓名最長13字紀錄。

3.2 总结

因为存储空间的限制,保存到 SIM 卡通讯录的姓名长度不能超过6个汉字,但在常规的软件开发中,应该放松对姓名长度的限制。如果需要考虑国际化,还应该了解外国人士的姓名限制,确认其他国家(如美国、日本)对公民姓名的规定。

3.3 相关链接

四、电子邮件地址

电子邮件,即 Email,相关标准包括 SMTP 协议(RFC 5321)和 IMF 格式(RFC 5322),前者定义 Email 如何传送,后者定义 Email 的消息格式。

4.1 RFC 文档对 Email 的定义

SMTP 协议中定义:

Reverse-path   = Path / "<>"

Forward-path   = Path

Path           = "<" [ A-d-l ":" ] Mailbox ">"

A-d-l          = At-domain *( "," At-domain )
              ; Note that this form, the so-called "source
              ; route", MUST BE accepted, SHOULD NOT be
              ; generated, and SHOULD be ignored.

At-domain      = "@" Domain

address-literal  = "[" ( IPv4-address-literal /
                IPv6-address-literal /
                General-address-literal ) "]"
                ; See Section 4.1.3

Mailbox        = Local-part "@" ( Domain / address-literal )

Local-part     = Dot-string / Quoted-string
              ; MAY be case-sensitive

其中:

注:由于 URL 地址只支持7位编码的 ASCII 字符集,因此对 Local-partDomainPath 来说,一个字节(8位)就是一个字符。

  • Local-part 最长 64 字节
  • Domain 最长 255 字节
  • Path 最长 256 字节
  • IPv4-address-literal 最长 4 字节(3*4+3=15个字符),格式 x.x.x.xx 表示十进制数字,每一位取值 0-255(1字节,最大2的8次方),用点(英文句号)进行分隔。
  • IPv6-address-literal 最长 16 字节(4*8+7=39个字符),常规格式 x:x:x:x:x:x:x:xx 表示1-4位十六进制数字,每一位取值 0-FFFF(2字节,最大2的16次方,或16的4次方),用冒号进行分隔。

因此一个完整的 Email 地址总长不超过 64+1+255=320 个字符。

结束了吗?还没有。因为受 Path 长度限制, Email 地址长度同时不应该超过 256-2=254 个字符(减去 <> 两个符号)。

4.2 业界对 Email 的处理

在标准之外,业界对 Email 的实际处理方式也需要考虑。

4.2.1 Gmail

打开 Gmail 的注册页面,可以看到如下的提示:

  • 用户名长度必须介于 6 到 30 个字符之间,不包括 "@gmail.com"。
  • 您可以使用字母、数字和英文句点。
  • 很抱歉,用户名的字符数须介于 6 到 30 之间。

在 Gmail 的帮助页面 可以看到更详细的说明:

创建用户名

如果您在注册 Google 帐号或 Gmail 时看到“不允许使用该用户名”,请按照以下准则操作。

注意:“Abuse”和“Postmaster”是系统预留的别名,您无法将其用作用户名或别名。有关详情,请参阅垃圾邮件和滥用行为政策。

字符长度

用户名的长度需为 6 至 30 个字符。用户名可以是字母、数字或符号的任意组合。

特殊字符

  • 用户名可以包含字母 (a-z)、数字 (0-9) 和点 (.)。
  • 用户名不得包含和符号 (&)、等号 (=)、下划线 (_)、撇号 (')、破折号 (-)、加号 (+)、英文逗号 (,)、尖括号 (<,>) 或连续多个点 (.)。
  • 用户名可以使用除点 (.) 之外的非字母数字字符作为开头或结尾。除此规则外,在 Gmail 地址中加点与否并无影响。

在 Gmail 地址中加点与否并无影响

如果有人在向您发送电子邮件时,不小心在地址中添加了点,您仍然可以收到这封邮件。例如,如果您的电子邮件地址是 johnsmith@gmail.com,则您也拥有所有加点版本的地址,如:

注意:如果您是通过公司、学校或其他单位帐号(比如 <您的域名>.com 或 <您的学校名称>.edu)使用 Gmail,在用户名中添加或删除点的确会改变您的电子邮件地址。要更改用户名中的点,请联系您的管理员。

4.2.2 Outlook

注册 Outlook 时,Email 地址的最大长度为 113,包括 "outlook.com" 或者 "hotmail.com"。

4.2.3 Yahoo Mail

注册雅虎邮箱时,Email 地址的最大长度为 32(注册页面中 input 限制为 maxlength="32"),不包括 "@yahoo.com"。

4.2.4 网易邮箱

  • 网易免费邮箱: 6~18个字符,可使用字母、数字、下划线,需以字母开头,不包括 "@163.com"、"@126.com"、"@yeah.net"
  • 网易VIP邮箱: 6~20个字母、数字、点或下划线,需以字母开头,不包括 "@VIP.163.com"

4.2.5 QQ 邮箱

在 QQ 邮箱的注册页面包含以下限制:

  • mail_length: "长度为3-18个字符",
  • mail_start_limit: "必须以a-z的英文字母(不分大小写)开头",
  • mail_end_limit: "由英文字母、数字结尾",
  • mail_char_limit: "由3-16个英文、数字、点、减号、下划线组成",
  • mail_special_limit: "点、减号、下划线不能连续出现两次或两次以上",

注:QQ 邮箱的域名包括 "@qq.com"、"@vip.qq.com"、"@foxmail.com"。

4.2.6 139邮箱

注册中国移动的139邮箱时,Email 地址的最大长度为 20(注册页面中 input 限制为 maxlength="20"),不包括 "@139.com"。

4.3 题外话:Email 地址中用户名之间的点是怎么回事

为了增强 Email 地址的可读性,同时避免一些爬虫抓取网页中的 Email,Gmail 等电子邮件服务商支持在 Email 地址的用户名中加入点 .,对 Gmail 来说,有没有点,效果是一样的。但并非所有网站都这样处理,有人曾做过统计(原文见 Stop Telling People There’s a Dot in Your Gmail Address—It Doesn’t Matter):

  • DOTS MATTER: Microsoft Outlook, Yahoo Mail, Apple iCloud
  • DOTS DON’T MATTER: Gmail, Facebook
  • DOTS STRICTLY PROHIBITED: Twitter

4.4 总结

如果是电子邮件服务商,可以对 Email 地址的长度进行严格的限制(如用户名控制在20个字符以内),但应该符合 RFC 相关标准,如果只是普通的录入,可以适当放宽条件,万一对方的 Email 地址就是70个字符呢。

最后再补充一点,支付宝账户最长多少字符呢?支付宝在注册时支持使用 Email 和手机号,注册页面中将 input 限制为 maxlength="100",最多允许100个字符。

4.5 相关链接

五、URL

在 RFC 的文档(HTTP 和 URI 标准)中并没有对 URL 的最大长度做出限制,但是具体的浏览器和服务器(如 Tomcat、Nginx、甚至 Node.js)在实现上可能会进行限制。

例如,Internet Explorer 将 URL 的最大长度限制在 2083 个字符,如果是发送 HTTP 请求,GET/POST 请求的 URL 最大长度为 2048 个字符(发送 POST 请求时,body 中的字符长度不受此限制,他们不是通过 URL 传输)。

5.1 总结

一般情况下不需要对 URL 长度过多关注,只有在发送 HTTP 请求时需要注意,如果发送的数据量很大,应该避免将数据拼接到 URL 中,通过 GET 方法请求,可以考虑改为 POST 方法,将数据放到请求体中。

5.2 相关链接