一个有趣的腾讯面试题

题目:设计一个身份证查询系统,将身份证号md5 之后存储,输入md5值查询对应的身份证号。
要求:成本低,查询速度快

设计思路:

  1. 将所有可能的身份证号做一个简单的统计计算数据量
  2. 根据数据量选择存储方式
  3. 查询

身份证生成规则:

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

地址码: 表示编码对象常住户口所在县(市、旗、区)的行政区划代码。对于新生儿,该地址码为户口登记地行政区划代码。需要没说明的是,随着行政区划的调整,同一个地方进行户口登记的可能存在地址码不一致的情况。行政区划代码按GB/T2260的规定执行。

出生日期码:表示编码对象出生的年、月、日,年、月、日代码之间不用分隔符,格式为YYYYMMDD,如19880328。按GB/T 7408的规定执行。原15位身份证号码中出生日期码还有对百岁老人特定的标识,其中999、998、997、996分配给百岁老人。

顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。

校验码: 根据本体码,通过采用ISO 7064:1983,MOD 11-2校验码系统计算出校验码。算法可参考下文。前面有提到数字校验码,我们知道校验码也有X的,实质上为罗马字符X,相当于10.

校验码算法

将本体码各位数字乘以对应加权因子并求和,除以11得到余数,根据余数通过校验码对照表查得校验码。

加权因子表

+-----------------------------------------------------------+ 
|位置序号|1 |2 |3 |4 |5 |6 |7 |8 |9 |10|11|12|13|14|15|16|17| 
+-----------------------------------------------------------+ 
|加权因子|7 |9 |10|5 |8 |4 |2 |1 |6 |3 |7 |9 |10|5 |8 |4 |2 | 
+-----------------------------------------------------------+ 

校验码表:

+----------------------------------------------------+ 
| 余数  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 
+----------------------------------------------------+ 
| 校验码| 1 | 0 | X | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2  | 
+----------------------------------------------------+ 

算法举例:

本体码为11010519491231002

  • 第一步:各位数与对应加权因子乘积求和1* 7+1 * 9+0 * 10+1 * 5+ *** =167
  • 第二步:对求和进行除11得余数167%11=2
  • 第三步:根据余数2对照校验码得X

**因此完整身份证号为:11010519491231002X **

预估数据量:

  1. 身份证号18位,前六位为地区码,中间八位为日期,日期后三位为顺序码,最后一位为校验位,占32个字节
  2. md5值为32位,占32个字节
  3. 计算最近100年数据,大约数据量为:3465x100x365x999=126346027500
  4. 数据以字符串存储,每条数据32+18=50位
  5. 则数据量为 126346027500 x 50=6317301375000B=6169239624k=6024648M=5883G=5.74T

存储方式有文件存储、关系型数据库存储和es存储等。从结果可以看到有接近6T的数据,如果存入数据库或es成本较高,这里选择以文件的方式存储。

那有没有方式压缩存储空间呢?

  1. 身份证号最后一位为校验位,可以不存储,省略掉这一位会节约1/50点空间
  2. 不以字符串的方式存储,将身份证号以uint64存储,md5值也转化成两个uint64存储。uint64占8阁字节空间,这样一条数据的空间由50降为了 24。最终数据量为2.74T,节约一半多的空间。

那现在有一个问题,每个文件多大合适呢?

如果文件太大,每次将文件读取到内存中耗时较长,如果文件太小,则会生成太多的文件可能超出系统的文件数限制。

这里可以参考数据库索引的存储方式,设定每个数据文件的大小(2.8T数据可以设置每个数据文件1G左右。

数据生成后如何查询?

  1. 遍历,依次读取文件,查找数据,效率太低
  2. 这里参考数据库索引的查询方式,首先将数据按md5值排序后存储多个文件,记录每个文件中md5值的范围,输入md5值确定文件,再读取文件使用二分查找。
  3. 这时查找数据只需要读取一个文件,但是每个文件都有几百兆的数据,查询效率还是太低,再参考一下数据库索引,这里将文件内部再分页,记录每页的范围,和文件所自身记录的起始值一起生成索引,索引结构如图所示:
89b91ea63b15a762099ccc0a6fdaf412.png

索引数据结构为:

# 为了简化存储,这里file1、file2、file3、file4 为该文件第一条数据的md5值,也是对应的文件名
# 页的大小固定,所以二级索引只需要按顺序记录每页的第一个md5值即可

indexes = { 
    "file1": ["md51", "md52", "md53", "..."],
    "file2": ["md51", "md52", "md53", "..."], 
    "file3": ["md51", "md52", "md53", "..."], 
    "file4": ["md51", "md52", "md53", "..."],  
} 

第一层索引为文件索引,首先通过md5值判断md5值所在文件,比如输入的 start1 > md5 > start1,可以判断结果可能在file1 中;

第二层为文件内索引,通过md5值判断所在的页,读取根据offset读取该页的全部数据,再通过二分查找找到对应的身份证号。

代码实现源码地址:https://github.com/gusibi/oneplus/tree/master/idgenerator

参考链接:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350

推荐阅读更多精彩内容