HTML5技术

绝对公平?破解北京机动车摇号的秘密 - FerventDesert(2)

字号+ 作者:H5之家 来源:博客园 2016-07-29 12:00 我要评论( )

几年前可以网上查到每个中签人的名字,还有下面的新闻: 2. 假如系统真的有破绽呢? (本段仅作为思想实验,开脑洞而已,请任何人不要对号入座。水表在门外,谢谢!) 通过控制种子,可以保证特定号码中签。但这样

几年前可以网上查到每个中签人的名字,还有下面的新闻:

image_1aoehnu6upet1lo7rfp13c5s8g3h.png-62.8kB

2. 假如系统真的有破绽呢?

(本段仅作为思想实验,开脑洞而已,请任何人不要对号入座。水表在门外,谢谢!)

通过控制种子,可以保证特定号码中签。但这样可能没法让所有要中签的都中签,策略是插入一些无效号。无效号能将特定的号码挤到对应必中的位置。

因为我们也无法判断参与抽签的每个号码都是有效的。而且你注意到了吗?2016年,每次摇号应该有15000个,但每次摇中的数量都差了一百多个,剩下的哪里去了?

通常计算机产生无效号,都是在短时间内集中产生的。如果能发现给每个用户分配编码的规则,就能反推用户的基本信息和注册时间,如果在统计上发现异常,就能找到这些无效号码,进而搜索随机种子。

沙漠君盯着这些长度都是13位的号码,统计了每一位上0-9字符出现的频率,发现它们都是等概率出现的。说明编码是按照某种随机算法生成的。什么工具的随机算法产生的字符长度是13位呢?我花了五六个小时破解这个逻辑:

我通过摇号程序签名,发现开发这套系统的公司叫taiji。我通过该公司网站的招聘信息和项目介绍,了解了验证软件是2014年1月6号下午开发开发,用了一个半月开发完,后台语言多半是C#。

据我猜测,每次会从后台随机产生不在数据库里的一个13位的随机数,作为新申请人的编码ID。理论上说,如果其系统用的是C#默认的随机生成器,那么就能通过暴力搜索的方法,找出每个编码生成的时间,也就是号码注册的时间,当然,这种计算的复杂度非常高,靠一己之力是很难完成的。

但我相信,以上这些推测都是瞎扯,这套系统一定是公平而完美的。

3.Hawk数据抓取工具

这是笔者耗时四年开发的数据抓取软件,目前已经开源,详情可参考沙漠之鹰的历史文章《如何从互联网抓取海量数据》。

4.生成真实摇号数据源代码 /// <summary> /// 代表一个抽签序号 /// </summary> public class Slot { public int Index { get; set; } public string ID { get; set; } } public class Period { public string Date { get; set; } public int Total { get; set; } public int Quota { get; set; } public string ID { get; set; } public string MD5 { get; set; } public int Seed { get; set; } } static void Main(string[] args) { var root = @"北京摇号\"; var table= File.ReadAllLines(root + "摇号列表.txt").Skip(1).Select(d=>d.Split('\t')).Select(d=>new Period(){ID=d[0],MD5=d[1],Seed=int.Parse(d[2])}).ToList(); foreach (var period in table) { Console.WriteLine(period.ID); List<Slot> slots=new List<Slot>(); var folder = $"{root}摇号文件\\PersonCommonNumberPeriod{period.ID}"; foreach (var file in Directory.GetFiles(folder)) { if (file.Contains("_")) slots.AddRange( File.ReadAllLines(file) .Select(d => d.Split(',')) .Select(d => new Slot {Index = int.Parse(d[0]), ID = d[1]})); else if(file.Contains("csv")) { var datas= File.ReadAllLines(file); period.Date = datas[3]; period.Total = int.Parse(datas[5]); period.Quota = int.Parse(datas[6]); } } Random random=new Random(period.Seed); SortedDictionary<string,int> selecteddict=new SortedDictionary<string, int>(); while (selecteddict.Count<period.Quota) { var selected = slots[random.Next(slots.Count)]; if(selecteddict.ContainsKey(selected.ID)) continue; selecteddict.Add(selected.ID,selected.Index); } File.WriteAllLines(folder+"\\"+"被选中号码.txt",selecteddict.Select(d=>d.Key+'\t'+d.Value)); } Console.WriteLine("fuck the world"); }

posted @

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 用Hashcat每秒计算1.4亿个密码,破解隔壁WIFI密码 - 方方和圆圆

    用Hashcat每秒计算1.4亿个密码,破解隔壁WIFI密码 - 方方和圆圆

    2017-02-07 10:03

  • 这个发现是否会是RSA算法的BUG、或者可能存在的破解方式? - Bro__超

    这个发现是否会是RSA算法的BUG、或者可能存在的破解方式? - Bro__超

    2017-01-21 14:01

  • 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~ - 南尘

    【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~ - 南

    2016-10-17 10:00

  • clip 属性剪裁绝对定位元素 - 黑睡莲

    clip 属性剪裁绝对定位元素 - 黑睡莲

    2016-07-01 17:00

网友点评
r