搬砖佬现在从事IOT行业,已经荒废了N年的数据结构基础,差不多都还给大学老师了。最近做的一个项目,让我重新拾起荒废的技能开战...
        项目中有一个需求:识别摄像头画面中的工程车,并获取车牌号。首先就想到了OpenCV,后来去工地现场考察,发现.......又特么的是现实很骨感的问题。工程车基本上都脏得要死,识别率简直低的不要不要的。于是变更了设计方案,使用超高频射频天线阵列,去感知附近的RFID标签。
那啥是RFID呢?我简单解释一下,超市里扣在毛巾袜子上的那个耳朵就是RFID标签的一种。当你没付钱就企图跑路时,超市门口的射频天线会滴滴滴,于是保安就过来抓小偷了。

好了,回到正题。RFID标签分为三个存储区块,分别是:

  1. EPC:超时里的物品条码,通常就是写在这个区段内。长度为14个字节(某些类型的标签只能用12个字节)。
  2. TID:标签的厂家ID,基本上都是只读的。这个区段一般是用来识别标签类型的,所以不可更改。
  3. USER:可以用来保存用户自定义的数据,长度不固定。欧标的可以写入192个bit,也就是24个字节。

这里有一个问题,USER区段虽然很美丽,并不是所有标签都有...所以,把ECP段的12个字节利用起来才是王道!
车牌号分为几个部分:

  1. 省份字头
  2. 首字母
  3. 号码
  4. 后缀

举两个栗子:湘UD12345,字头是“湘”,首字母“U”,号码“D12345”,没有后缀;湘U1234挂,字头“湘”,首字母“U”,号码“1234”,后缀“挂”。

全国每个身份一个字头,加上“使领”这两个特殊字头(工程车可以忽略不考虑特殊字头),后缀有这几种情况:“挂学警港澳使领”,工程车同样可以忽略这些情况。归纳一下,号牌可能出现的数量组合有:34263636363636*36种。MMP,12个字节不够用啊(光一个汉字就要吃掉4个byte,UTF8模式下,单个字符最多可能占用4个byte,一般是3个byte)。

换个思路吧,不然又无解了。大学时候的计算机文化基础课程,2进制8进制10进制16进制的换算...我特么的撸个34进制,36进制好不好?答案是非常好。此题有解!这样子一来,车牌号可以压缩到28个bit来表示,也是就说4个字节就可以搞定。

强迫症在这个时候又开始发作,12个字节,还剩那么多怎么办?别浪费。于是就开始作死,加上4个bit的随机数,加上4个byte的时间戳,还剩2个byte用来保存crc16,简直就是完美。这样又把以前动态密文的设计思想给带进来了。

贴一段解算编码算法的Python实例代码:(从解算代码可以反推编码算法,我不喜欢留邮箱一族,也不喜欢只要源码光抄作业的人)

在算法的加持下,12个字节可以记录完整的车牌号,同时还可以记录制卡时间,还可以防伪,完美的不要不要的。

1.png
2.png

        常见的加密算法,只要明文固定,秘钥固定,那么加密结果也是固定。于是这就产生了碰撞的可能性,为穷举破解提供了机会。那么有没有可能设计一种算法,使得在相同明文与秘钥的前提下,每次加密的结果都不一样呢?
        看起来似乎有点不太可能,但是我们如果换个思路:明文打乱后再加密;加密的时候带上时间因子。有了这两个相对比较“随机”的因素,那么加密的结果就有可能达到上述目的。理想很丰满,现实很骨感。虽然思路有了,但是怎么打乱明文?总不能写死(固定把XX字节挪动到YY位置)吧,这跟不打乱没有本质上的区别。所以,又回到时间这个因子上面来。有一个假设是成立的:每次需要加密的时间点是不同的(杠精免疫),so...用时间因子与密文的hash值,可以构造出一个比较“随机”的打乱方式。其次,有个常识:Base64变化后,字符串长度会变成原来的1.3倍左右(每3个字节变成4个字节,例如:9个字节长度的字符串,base64变换后,会变成12个字节;10个字节的字符串,会变成15个字节)。现在万事俱备只欠东风。


        话不多说,上菜:这是我在2016年的时候,在某500强企业撸的代码...因为APP鉴权的秘钥固定,送检时总是被安全部门打回,被逼无奈连夜撸的代码,这回安全部门傻眼了。搬砖佬从此在某500强企业的某项目组中一战成名。如今项目已经过了保密期,所以搬砖佬才敢把源码与算法设计思想共享出来...

        加解密算法,包括PHP、JAVA、Objective-C三种语言的算法实现以及Demo,可以用于APP与WEB后端加密通讯。 算法简介:

  1. 加入了时间因子混淆,因此相同的明文,每次加密的结果都不一样,但是只要条件符合,均可以解密出正确的明文。
  2. 加解密key均转换为数组,且做随机乱序(伪随机,根据密钥与报文长度做乱序),以增加破解难度(基于Ron Rivest提出的RC4算法做的改进),因此保证密钥不泄露是保密的关键工作。
  3. PHP端在加密时,可以指定超时时间(单位:秒),即超时后,密文无法被解密,以增强安全性。JAVA、Objective-C暂时不支持指定超时参数。
  4. 三个版本的加解密的KEY需要统一,否则无法进行数据交换。这个问题只要智商正常,应该都能理解。
  5. 三个版本的加解密算法,对于字符串处理,默认都使用UTF8编码…不解释。
  6. 三个版本都包含了Demo。PHP的童鞋请关注PHP源码第55-63行所演示的使用方法;JAVA的童鞋请看源码文件最后的main入口;Objective-C的童鞋看main.m 源码。

有条件的可以自己去Github看,没条件的,请下载附件AuthCode_RC4-master.zip