Re: [问题] 检核码规则 机器学习

楼主: Schottky (顺风相送)   2022-01-29 18:09:58
※ 引述《ozone (Life)》之铭言:
: 请问检核码规则分析 利用machine learning来解是好的方法吗?
: 我有一批资料,由9个数字组成,第10个数字是检核码,不知其规则
: 利用keras建模后却train不起来
: 于是尝试建立测试资料,检核码的规则是前9码mod 10
: 将9码input转成one-hot encoding成 9 x 10 array
: 建dense network但仍然train不起来
: code在此:
: https://stackoverflow.com/questions/70843702/learn-checksum-rule-with-keras
: 不晓得是哪里弄错了?
放假就是要玩解谜小游戏
这是原 PO 贴在 Stack Overflow 的原始资料
https://drive.google.com/file/d/1Q4tk64NOGuyItLULjhth1kgaPU0zpRkI/view
资料是 003000008J 这种格式,九个数字跟着一个英文字母,
看起来英文字母就是检核码了,只是还不知道和数字如何对应。
但其实哪一位才是检核码、字母如何对应根本不重要,
我们想知道的只有“序号如何判断是否有效”。总之现在先随便假设。
☆ ☆ ☆
先把每个位数定个名字,X0, X1, X2, X3, X4, X5, X6, X7, X8, 最后的字母叫 S
那我们先从 X8 开始,寻找序号中有没有除了 S 之外其他数字全部相同只有 X8 不同
的组合,拿来比较 S 相对于 X8 的变化
003003188 ==> A 003004622 ==> B 003007744 ==> C
003003189 ==> B 003004623 ==> C 003007745 ==> D
003021375 ==> D 003004798 ==> E 003042690 ==> F
003021376 ==> E 003004799 ==> F 003042691 ==> G
003018456 ==> G 003040268 ==> H 003040023 ==> I
003018457 ==> H 003040269 ==> I 003040024 ==> J
003049387 ==> J
003049388 ==> A
蛮幸运的,光是数字差 1 的就找到很多,那观察之后发现只要 X8 的数字 +1,
S 的字母就会按照一个固定的规则推移,共有上面列出的十种,还能串成一个环
A > B > C > D > E > F > G > H > I > J > A > B > C > D > .....
还刚好是十个字母照顺序排,那是不是可以假设字母对应 0-9 十个数字呢?
当然我们只是串成环,并不知道从哪开始是 0,但这其实不重要,
反正先随便假设 A=0, B=1, ..... I=8, J=9
☆ ☆ ☆
以此类推,我们可以继续发掘其他位数的规则
X7 也有类似的环圈规则,但却有两组环
A > C > E > G > I > A
B > D > F > H > J > B
代换成 X8 假设的英文-数字对应关系:
0 > 2 > 4 > 6 > 8 > 0
1 > 3 > 5 > 7 > 9 > 1
发现了吗?偶数一组,奇数一组,每次 +2,这是否代表 X7 在检核规则中被乘以 2?
☆ ☆ ☆
X6: A > D > G > J > C > F > I > B > E > H > A (单环)
X5:
A > E > I > C > G > A
B > F > J > D > H > B
双环,且每次+4
X4: 这次出现了五环
A <-> F , B <-> G , C <-> H , D <-> I , E <-> J
0 <-> 5 , 1 <-> 6 , 2 <-> 7 , 3 <-> 8 , 4 <-> 9
你想到什么?这明显是乘以 5
X3: 又是双环
A > G > C > I > E > A
B > H > D > J > F > B
X0, X1, X2 资料不足,前三码只有 003, 800, 999 三种,但这个可以先不管
到时候随便乱凑一种自圆其说的规则就好,真的不行就分成三种规则照前三码分辨
好的现在我们把 X8 的乘数就当作是 1,把假设的数字 0-9 代入英文字母 A-J
就能得出下面的检核规则: (其中 X0, X1, X2 的系数是随便猜随便凑的)
(X0*9 + X1*8 + X2*7 + X3*6 + X4*5 + X5*4 + X6*3 + X7*2 + X8) mod 10 = S
而 A=0, B=1, C=2, D=3, E=4, F=5, G=6, H=7, I=8, J=9
再把这个规则套用回已知的序号,发现全部吻合,可以宣布成功了 (撒花)
8361 passed.
0 failed.
☆ ☆ ☆
那也许会有人说,今天是英文字母照顺序排,才被我发现 X8 是乘 1,顺利破解,
如果把英文字母打乱呢?如果第一个挑选的是 X6 (百位数) 呢?它也是单环啊?
其实这样还是可以把规则解出来,只是规则的外观会变成另一套,但一样适用。
假设我们把 X6 的单环英文字母当成正确顺序,那就会变成这样:
A=0, D=1, G=2, J=3, C=4, F=5, I=6, B=7, E=8, H=9
(我们并不知道哪一个才是0,但到最后发现不合可以再改,或是给公式加个常数项)
套用到其他位数的规则后,会得出新的公式
(X0*3 + X1*6 + X2*9 + X3*2 + X4*5 + X5*8 + X6*1 + X7*4 + X8*7) mod 10 = S
再套用回所有已知序号验证
8361 passed.
0 failed.
这个规则也是可以用的,神奇吧?所以规则并不是只有一条。
把英文字母打乱也是没有用的,环圈会告诉我们顺序,即使顺序不只一种排法。
我们还可以发现一个有趣的事实,X4 有五环,它的系数是 5 不会变
X3, X5, X7 有双环,它们的系数一定是偶数 (2的倍数)
知道这个特性也可以帮助判断乘数
但只有偶数和 5 有办法用环数判断,因为 2 和 5 是 10 的质因子
3, 7, 9 这三个数和 10 互质,所以用它当乘数只会出现单环
☆ ☆ ☆
回到原 PO 的问题,神经网络 (深度学习) 一般不是用来解这个检核码规则的,
这属于密码学 (Cryptography) 的密码分析 (Cryptanalysis) 在探讨的问题。
但你去看密码学课本,没有一本会讲到如何破解身分证规则,因为这个太简单了,
我上面也没用到任何密码学工具,只用了四则运算,连 mod 都不算是真正“用到”
☆ ☆ ☆
最后附上我用的工具程式
破解的过程,大部份是靠人眼观察,人工寻找可以用的资料组合,
但身为 Python 的初学者,我还是写了两支 Python 程式,
一支帮助过滤出原始资料中 8 个数字相同的组合以便观察规则
一支用在已经找出规则之后,检验有多少笔序号是符合这个规则的
https://ideone.com/24noQ6
读入 charno.txt 并且输出 output0.txt ~ output8.txt
找出只有 X0 ~ X8 单一位数字不同的序号组,集中放置方便观察规律
https://ideone.com/WOms7q
读入 charno.txt 检验每一组序号是否符合我们猜想的检核码公式
写过之后我好像对于 dictionary, list, string 的处理更多了解了一点,
是个不错的练习,推荐各位试试,但不必把这程式看得太重要,它只是辅助
作者: s0914714 (YA)   2022-01-29 22:21:00
作者: mantour (朱子)   2022-01-29 23:03:00
作者: ozone (网球拍回家了)   2022-01-30 12:40:00
推!谢谢你!
作者: coyoteY (マジジョテッペン)   2022-01-30 13:19:00
很有趣!
作者: yimean (温柔杀手)   2022-01-31 14:44:00
感谢分享
作者: miaomiaojiao (QQ)   2022-02-11 00:25:00
感谢分享
作者: unmolk (UJ)   2022-02-13 11:28:00

Links booklink

Contact Us: admin [ a t ] ucptt.com