由suctf一道题学到的中国余子式定理

文章以word形式发至邮箱:

minwei.wang@dbappsecurity.com.cn

有偿投稿,记得留下你的姓名联系方式哦~

中国余式定理即俗称的韩信点兵,又称孙子点兵、鬼谷算、秦王暗点兵,在先秦战国时代就已经有了记载。

有一道题,是这样写的:

“今有物不知其数,三三数之余二,五五数之余三,七七数之余二,问物几何?”,这首诗的意思是有一个数,除以三余数为二,除以五余数问三,除以七余数为二,求这个数。

解法:

①令除数n1=3,n2=5,n3=7两两互质,然后将除数相乘得到一个n,n=n1n2n3=105;

②令余数x1=2,x2=3,x3=2,令乘积除以每个除数,得到一组数,M1=n/n1=105/3=35,M2=n/n2=105/5=21,M3=n/n3=105/7=15;

③利用辗转相除法或直接计算乘法反元素得到一组数:

s1=(mod n1) = ≡ 2 (mod 3)

s2=(mod n2) = ≡ 1 (mod 5)

s3=(mod n3) = ≡ 1 (mod 7)

④最后将每对M、x、s求乘积并将每对数据相加求和,将结果对n取余数,就可以得到最终的结果。

X = (x1M1s1 + x2M2s2 + x3M3s3) (mod n)

= (2×35×2 + 3×21×1 + 2×15×1) (mod 105)

= 23

中国余式定理:令n1、n2、……、nk为两两互质的整数,令n=n1n2……nk。联立方程组:

在集合{0,1,2……n-1}有唯一解:

x=

其中Mi=n/ni,si(mod ni) (n=0,1,2,…k)

上边这道题用程序来解的话是这样的:

import gmpy2

n = [3,5,7]

x = [2,3,2]

N = 1

for i in n:

N *= i

M = []

for i in n:

M.append(N/i)

s = []

for i in range(len(n)):

s.append(gmpy2.invert(M[i],n[i]))

#print s

sum = 0

for i in range(len(n)):

sum += x[i] * M[i] * s[i]

X = sum % N

print X

运行结果:

看suctf的一道题目:

Game.py内容:

import flag

flag = flag.flag

sands = int(flag[5:-1].encode("hex"), 16)

holes = [257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373]

with open("sand.txt", "w") as f:

for i in range(len(holes)):

sand = sands % holes[i]

f.write(str(sand)+"\n")

意思是将flag{}中的内容进行十六进制,然后转换成十进制对holes中的数据做求余运算,放入sand.txt中。利用中国余子式定理可以得到flag。

还是上边的脚本,稍作修改:

#coding:utf-8

import gmpy2

with open('sand.txt','r') as f:

sand_src = f.readlines()

sands = []

for i in sand_src:

sands.append(int(i.replace('\n','')))

holes = [257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373]

n = 1

for i in holes:

n *= i

M = []

for i in holes:

M.append(n/i)

s = []

for i in range(len(holes)):

s.append(gmpy2.invert(M[i],holes[i]))

#print s

x = 0

for i in range(len(sands)):

x += sands[i] * M[i] * s[i]

res = x % n

#print res

encode_hex = hex(res).replace('0x','').replace('L','')

decode_hex = encode_hex.decode('hex')

flag = "flag{" + decode_hex + "}"

print flag

运行结果:

题目虽不是很难,但对于我来说这个定理也是头一次听说,头一次接触,倒也学到了不少。

-END-

原文发布于微信公众号 - 安恒网络空间安全讲武堂(cyberslab)

原文发表时间:2018-06-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏谦谦君子修罗刀

程序员面试闪充--UML类图关系

我们曾借白茶清欢等一个人,曾借花开花落叹宠辱不惊。今天借着类图来了解面向对象又有何不可呢? 小视频传送门:小视频传送门 ? 对象模型中,类图是来描述系统的静态结...

33312
来自专栏数据结构与算法

P1325 雷达安装

题目描述 描述: 假设海岸线是一条无限延伸的直线。它的一侧是陆地,另一侧是海洋。每一座小岛是在海面上的一个点。雷达必须安装在陆地上(包括海岸线),并且每个雷达都...

3316
来自专栏AI科技大本营的专栏

你一定能看懂的算法基础书(代码示例基于Python)

本文引自图灵教育《算法图解》 你一定能看懂的算法基础书;代码示例基于Python;400多个示意图,生动介绍算法执行过程;展示不同算法在性能方面的优缺点;教会...

4947
来自专栏chenjx85的技术专栏

leetcode-40-组合总和 II

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

1211
来自专栏冰霜之地

神奇的德布鲁因序列

数学中存在这样一个序列,它充满魔力,在实际工程中也有一部分的应用。今天就打算分享一下这个序列,它在 Google S2 中是如何使用的以及它在图论中,其他领域中...

1733
来自专栏大数据挖掘DT机器学习

【手把手教你做项目】自然语言处理:单词抽取/统计

作者 白宁超 成都信息工程大学硕士。 近期关注数据分析统计学、机器学习。 原文:http://www.cnblogs.com/baiboy/p/zryy1.ht...

3065
来自专栏Crossin的编程教室

【每周一坑】乒乓数

刚从假期回来,又要迎接周末,各位看官想必都很辛苦,所以本周每周一坑为大家准备一道简单的甜点题目,本题取材于伯克利大学 CS61 课程 homework02。 求...

2816
来自专栏数据结构与算法

1163 访问艺术馆

 时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解  查看运行结果 题目描述 Description     皮尔...

2757
来自专栏有趣的Python

c++实战-(一)-走出迷宫

走出迷宫 走出规则: 左手规则 & 右手规则 原则:保证手始终触墙 结果:走出迷宫 情况1:有入有出。(特殊情况,出入口是一个) ? 架构描述: 迷宫类(Maz...

2914
来自专栏前端吧啦吧啦

数据结构(一)之基础知识

35510

扫码关注云+社区