2018 SUCTF magic

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kevin66654/article/details/80554932

当时做题的时候得到的式子:

(m[0] & key) % 2 == ?

(m[1] & key) % 2 == *

其中?和 * 很明显,不是0就是1啊!所以不妨换一种思路,如果我们把m和key都转化为二进制数,会发生什么!

M表示m展开后的矩阵,K表示key展开之后的向量,C为cipher.txt转成的01向量,即有:MK = C

矩阵乘法!二进制下的!也就是说,在有限域GF(2)中,有已知的矩阵M和密文C,要求密钥K!

答案是:高斯消元


题解地址:

https://www.xctf.org.cn/library/details/2ff21f569a791e21cbd6ce0d4675a9de5ec2373a/

https://findneo.tech/180527suctf/#Magic

第二篇wp的写法姿势特别好:(论算法的重要性)

翻译一下这行代码:

read_to_int_array = lambda x:[map(int,list(bin(int(line,16))[2:].zfill(dim))) for line in open(x).readlines()]

举例:

s = "e6aec69625130b77330f5b5abaf4155c862b625dce1bbfbd3fb54ea3d914b91"
print int(s,16)
print bin(int(s,16))
print bin(int(s,16))[2:]
print bin(int(s,16))[2:].zfill(dim)
print list(bin(int(s,16))[2:].zfill(dim))
print map(int,list(bin(int(s,16))[2:].zfill(dim)))

结果是这样的:

6521297322318485135397962758917330134336256120928714851050733785157196663697
0b111001101010111011000110100101100010010100010011000010110111011100110011000011110101101101011010101110101111010000010101010111001000011000101011011000100101110111001110000110111011111110111101001111111011010101001110101000111101100100010100101110010001
111001101010111011000110100101100010010100010011000010110111011100110011000011110101101101011010101110101111010000010101010111001000011000101011011000100101110111001110000110111011111110111101001111111011010101001110101000111101100100010100101110010001
0000111001101010111011000110100101100010010100010011000010110111011100110011000011110101101101011010101110101111010000010101010111001000011000101011011000100101110111001110000110111011111110111101001111111011010101001110101000111101100100010100101110010001
['0', '0', '0', '0', '1', '1', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '1', '0', '1', '1', '0', '0', '0', '1', '1', '0', '1', '0', '0', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '1', '0', '1', '0', '0', '0', '1', '0', '0', '1', '1', '0', '0', '0', '0', '1', '0', '1', '1', '0', '1', '1', '1', '0', '1', '1', '1', '0', '0', '1', '1', '0', '0', '1', '1', '0', '0', '0', '0', '1', '1', '1', '1', '0', '1', '0', '1', '1', '0', '1', '1', '0', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1', '1', '0', '1', '0', '1', '1', '1', '1', '0', '1', '0', '0', '0', '0', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', '1', '1', '0', '0', '1', '0', '0', '0', '0', '1', '1', '0', '0', '0', '1', '0', '1', '0', '1', '1', '0', '1', '1', '0', '0', '0', '1', '0', '0', '1', '0', '1', '1', '1', '0', '1', '1', '1', '0', '0', '1', '1', '1', '0', '0', '0', '0', '1', '1', '0', '1', '1', '1', '0', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '1', '1', '0', '1', '0', '0', '1', '1', '1', '1', '1', '1', '1', '0', '1', '1', '0', '1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '0', '1', '0', '1', '0', '0', '0', '1', '1', '1', '1', '0', '1', '1', '0', '0', '1', '0', '0', '0', '1', '0', '1', '0', '0', '1', '0', '1', '1', '1', '0', '0', '1', '0', '0', '0', '1']
[0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1]

转为10进制,再转为二进制,去掉前面的0b,然后补全256位,再拆开成256个0或1,拼到另外一个list中

接下来就是处理高斯消元了

dim = 256
read_to_int_array = lambda x:[map(int,list(bin(int(line,16))[2:].zfill(dim))) for line in open(x).readlines()]
cipher = read_to_int_array('cipher.txt')[0]
magic = read_to_int_array('magic.txt')

'''
s = "e6aec69625130b77330f5b5abaf4155c862b625dce1bbfbd3fb54ea3d914b91"
print int(s,16)
print bin(int(s,16))
print bin(int(s,16))[2:]
print bin(int(s,16))[2:].zfill(dim)
print list(bin(int(s,16))[2:].zfill(dim))
print map(int,list(bin(int(s,16))[2:].zfill(dim)))
'''

for j in range(dim):
	for i in range(j,dim):
		if magic[i][j] == 1:
			magic[i],magic[j] = magic[j],magic[i]
			cipher[i],cipher[j] = cipher[j],cipher[i]
			break
	for i in range(dim):
		if magic[i][j] == 1 and i != j:
			for k in range(dim):
				magic[i][k] ^= magic[j][k]
			cipher[i] ^= cipher[j]

print "flag{%s}"%hex(int(''.join(map(str,cipher)),2))[2:-1].decode('hex')
就可以看到flag了咯!~
展开阅读全文

Magic Board

09-30

Problem DescriptionnSths is a happy boy~nnSths has got a Magic Board for his birthday gift! A Magic board is an N*M sized grids which were painted by black and white. According to the parity of N and M, the Magic Board would be a little different, but it can be guaranteed that any two adjacent grids are painted by different colors, and the amount of black grid is not less than white ones.nnnThe Magic Board is called MAGIC because it is formed by a Chain. A Chain is a set of grids in which a grid has at most 2 adjacent grids and there are only 2 grids which has only 1 adjacent grid. Those two special grids are called the endpoints of the Chain.nnThe joint between two adjacent grids is very flexible. It can be rotate by any angle. Here’s an example of transforming a Chain into a Magic BoardnnnnnThe Chain was connected by a Magic String. The existence of Magic String relies on the power of fengshui. But recently the fengshui in Beijing was ruined because there is a university installing air-conditionor (which also cause the HUGE RAIN in Beijing).So the Magic String disappears, and the Magic Board is totally fell apart.nnSths feels upset, because he really likes the Magic Board (since it can form a lot of things). So he is thinking about how to reconstruct it. The only thing Sths has got now is the separated grids. But surprisingly, Sths finds out that there are differences between these grids.nn1. There are black grids and white grids.n2. There are three different grids in the same color because the Magic String goes through it in 3 different ways shown below:nnnSo there are 6 different kinds of grids. Now Sths has counted the amount of each kind of grids, he wants to know: by using the grids in his hand, how many kinds of legal Chains (which can form an N*M sized Magic Board) can be constructed.n  nWe shall say two Chains is the same if and only if the standard expression of these two Chains is the same.nnThe standard expression is a set of numbers which decided by following method:nn1. Starting from one of a Chain's endpoint.n2. Write down the color of the grids (1 for black and 0 for white) before direction changing.n3. Write down 2 then change direction and repeat Step 2 until reaching another endpoint of the Chain.n4. Choose the expression which lexicographical lower between the two expressions just generated since there are two endpoints.nnFor example, the standard expression of the example of “N=M=3” is “10120120120212” (another expression is “10212012012012”, which is lexicographical greater than standard expression). And the standard expression of the example of “N=M=4” is “01012010210120120120212”.n nnInputnThere are Multiple Test CasesnFor each case, there will be six integer numbers in one line, N, M, BO, BA, WO, and WA, indicating the number of rows and columns, the amount of “Black and Opposite” grids, the amount of “Black and Adjacent” grids, the amount of “White and Opposite” grids, the amount of “White and Adjacent” grids.nn2<=N*M<=30nnThe input end with a line of 0 0 0 0 0 0.n nnOutputnFor each case, output the kinds of legal Chains that can be constructed by given grids.n nnSample Inputn3 3 1 2 2 2n3 3 0 3 3 1n5 5 5 6 5 7n0 0 0 0 0 0n nnSample Outputn1n1n4n 问答

没有更多推荐了,返回首页