由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 条评论
登录 后参与评论

相关文章

来自专栏前端吧啦吧啦

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

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

1163 访问艺术馆

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

2837
来自专栏冰霜之地

神奇的德布鲁因序列

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

2133
来自专栏用户2442861的专栏

百度 阿里 华为 腾讯 谷歌面试笔试题及解析

点评:其余题目请参见:http://blog.csdn.net/doc_sgl/article/details/11695671。 2、一个有10亿条记录...

6243
来自专栏chenjx85的技术专栏

leetcode-40-组合总和 II

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

1341
来自专栏js编程在工科课程中的简单应用

5.2.1 二维导热算例-热导的概念

材料类,描述材料的参数,如密度、比热和初始温度等,这里特别给出了凝固潜热;这里要注意Math.pow(2,0)的意义,读者自己琢磨,用于判断相邻控制体的...

1070
来自专栏互联网开发者交流社区

SQL基础日期函数

1625
来自专栏前端吧啦吧啦

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

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

2017.10.23解题报告

预计分数:100+60+0=160 实际分数:100+80+0=180 T1 题目描述 现在有一个字符串,每个字母出现的次数均为偶数。接下来我们把第一次出现的字...

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

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

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

5397

扫码关注云+社区

领取腾讯云代金券