[原创]KCTF2021春季赛第四题 英雄救美
source link: https://bbs.pediy.com/thread-267621.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
程序无壳,ida打开,流程很清晰
- main 函数
关键在两个验证函数:checkformat_401240和checksudoku_401000 - checkformat_401240
此函数负责将输入根据字符表分段匹配,转换为1-9,再结合后面的checksudoku_401000函数,推测为数独游戏;
数独的i行输入在字符表[i9:i9+9]段内查找,根据位置转为1-9,
每行结束,添加本行已给出数据的个数 - checksudoku_401000
此函数负责验证数独writeup
反推,先解数独,再转格式
import
time
t0
=
time.time()
class
point:
def
__init__(
self
, x, y):
self
.x
=
x
self
.y
=
y
self
.available
=
[]
self
.value
=
0
def
rowNum(p, sudoku):
row
=
set
(sudoku[p.y
*
9
:(p.y
+
1
)
*
9
])
row.remove(
0
)
return
row
# set type
def
colNum(p, sudoku):
col
=
[]
length
=
len
(sudoku)
for
i
in
range
(p.x, length,
9
):
col.append(sudoku[i])
col
=
set
(col)
col.remove(
0
)
return
col
# set type
def
blockNum(p, sudoku):
block_x
=
p.x
/
/
3
block_y
=
p.y
/
/
3
block
=
[]
start
=
block_y
*
3
*
9
+
block_x
*
3
for
i
in
range
(start, start
+
3
):
block.append(sudoku[i])
for
i
in
range
(start
+
9
, start
+
9
+
3
):
block.append(sudoku[i])
for
i
in
range
(start
+
9
+
9
, start
+
9
+
9
+
3
):
block.append(sudoku[i])
block
=
set
(block)
block.remove(
0
)
return
block
# set type
def
initPoint(sudoku):
pointList
=
[]
length
=
len
(sudoku)
for
i
in
range
(length):
if
sudoku[i]
=
=
0
:
p
=
point(i
%
9
, i
/
/
9
)
for
j
in
range
(
1
,
10
):
if
j
not
in
rowNum(p, sudoku)
and
j
not
in
colNum(p, sudoku)
and
j
not
in
blockNum(p, sudoku):
p.available.append(j)
pointList.append(p)
return
pointList
ret
=
None
def
tryInsert(p, sudoku):
global
ret
availNum
=
p.available
for
v
in
availNum:
p.value
=
v
if
check(p, sudoku):
sudoku[p.y
*
9
+
p.x]
=
p.value
if
len
(pointList) <
=
0
:
t1
=
time.time()
useTime
=
t1
-
t0
ret
=
showSudoku(sudoku)
print
(
'\nuse Time: %f s'
%
(useTime))
# print(ret)
return
# exit()
p2
=
pointList.pop()
tryInsert(p2, sudoku)
sudoku[p2.y
*
9
+
p2.x]
=
0
sudoku[p.y
*
9
+
p.x]
=
0
p2.value
=
0
pointList.append(p2)
else
:
pass
def
check(p, sudoku):
if
p.value
=
=
0
:
print
(
'not assign value to point p!!'
)
return
False
if
p.value
not
in
rowNum(p, sudoku)
and
p.value
not
in
colNum(p, sudoku)
and
p.value
not
in
blockNum(p, sudoku):
return
True
else
:
return
False
def
showSudoku(sudoku):
result
=
[]
for
j
in
range
(
9
):
for
i
in
range
(
9
):
result.append(sudoku[j
*
9
+
i])
print
(
'%d '
%
(sudoku[j
*
9
+
i]), end
=
'')
print
('')
return
result
v13
=
r
"$BPV:ubfYp}]DtN>aT^MGmJQ#*Hr`O'wjic0!hdy{oZz-@n+?&%s_/g<e[W)XUxRFSLRA;.l=CEkvK-(q"
# def checkformat(myinput=r":u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2"):
def
checkformat(myinput):
a3
=
[]
i
=
0
j
=
0
k
=
0
strlens
=
len
(myinput)
while
1
:
tmpchr
=
myinput[j]
if
ord
(tmpchr) >
ord
(
'0'
)
and
ord
(tmpchr) <
=
ord
(
'9'
):
# break
if
i
+
ord
(tmpchr)
=
=
ord
(
'9'
):
i
=
0
k
+
=
9
j
+
=
1
if
j >
=
strlens:
printf(a3)
return
1
continue
m
=
k
if
(k >
=
81
):
return
0
while
ord
(tmpchr) !
=
ord
(v13[m]):
m
+
=
1
if
(m >
=
81
):
return
0
v9
=
m
%
9
+
1
a3.append(v9)
i
+
=
1
j
+
=
1
# if j >= strlens:
# print('##',a3)
# return 1
return
-
1
DEBUG
=
True
def
printf(
*
args):
if
DEBUG:
print
(
*
args)
if
__name__
=
=
'__main__'
:
sudoku
=
[
0
,
4
,
0
,
7
,
0
,
0
,
0
,
0
,
0
,
9
,
2
,
0
,
0
,
0
,
0
,
6
,
0
,
7
,
8
,
3
,
0
,
0
,
0
,
5
,
4
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
3
,
0
,
0
,
0
,
0
,
0
,
0
,
2
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
5
,
0
,
0
,
0
,
4
,
0
,
0
,
0
,
4
,
9
,
0
,
0
,
0
,
7
,
1
,
3
,
0
,
5
,
0
,
0
,
0
,
0
,
9
,
4
,
0
,
0
,
0
,
0
,
0
,
8
,
0
,
6
,
0
]
pointList
=
initPoint(sudoku)
showSudoku(sudoku)
print
(
'\n'
)
p
=
pointList.pop()
tryInsert(p, sudoku)
result
=
ret
# result="""5 4 6 7 1 9 2 3 8
# 9 2 1 8 3 4 6 5 7
# 8 3 7 6 2 5 4 1 9
# 7 1 8 4 6 3 9 2 5
# 4 5 3 2 9 1 7 8 6
# 6 9 2 5 8 7 1 4 3
# 2 8 4 9 5 6 3 7 1
# 3 6 5 1 7 2 8 9 4
# 1 7 9 3 4 8 5 6 2 """.split()
# result = list(map(int, result))
strdata
=
v13
printf(
'#sudoku:'
, sudoku)
printf(
'#result:'
, result)
n
=
0
need
=
[]
my
=
''
currentsize
=
0
for
i
in
range
(
81
):
if
sudoku[i] !
=
result[i]:
currentsize
+
=
1
need.append(result[i])
my
+
=
strdata[n
*
9
+
result[i]
-
1
]
if
(i
+
1
)
%
9
=
=
0
:
my
+
=
chr
(
ord
(
'9'
)
-
currentsize)
currentsize
=
0
n
+
=
1
printf(need)
r
=
checkformat(my)
if
r:
print
(
'checkov flag:\n'
, my, sep
=
'')
# from hashlib import md5
# x=md5(my.encode()).hexdigest()
# print(x)
# print('########################')
0 4 0 7 0 0 0 0 0
9 2 0 0 0 0 6 0 7
8 3 0 0 0 5 4 0 0
0 1 0 0 0 3 0 0 0
0 0 0 2 0 1 0 0 0
0 0 0 5 0 0 0 4 0
0 0 4 9 0 0 0 7 1
3 0 5 0 0 0 0 9 4
0 0 0 0 0 8 0 6 0
5 4 6 7 1 9 2 3 8
9 2 1 8 3 4 6 5 7
8 3 7 6 2 5 4 1 9
7 1 8 4 6 3 9 2 5
4 5 3 2 9 1 7 8 6
6 9 2 5 8 7 1 4 3
2 8 4 9 5 6 3 7 1
3 6 5 1 7 2 8 9 4
1 7 9 3 4 8 5 6 2use Time: 0.031022 s
#sudoku: [0, 4, 0, 7, 0, 0, 0, 0, 0, 9, 2, 0, 0, 0, 0, 6, 0, 7, 8, 3, 0, 0, 0, 5, 4, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 4, 9, 0, 0, 0, 7, 1, 3, 0, 5, 0, 0, 0, 0, 9, 4, 0, 0, 0, 0, 0, 8, 0, 6, 0]
#result: [5, 4, 6, 7, 1, 9, 2, 3, 8, 9, 2, 1, 8, 3, 4, 6, 5, 7, 8, 3, 7, 6, 2, 5, 4, 1, 9, 7, 1, 8, 4, 6, 3, 9, 2, 5, 4, 5, 3, 2, 9, 1, 7, 8, 6, 6, 9, 2, 5, 8, 7, 1, 4, 3, 2, 8, 4, 9, 5, 6, 3, 7, 1, 3, 6, 5, 1, 7, 2, 8, 9, 4, 1, 7, 9, 3, 4, 8, 5, 6, 2]
[5, 6, 1, 9, 2, 3, 8, 1, 8, 3, 4, 5, 7, 6, 2, 1, 9, 7, 8, 4, 6, 9, 2, 5, 4, 5, 3, 9, 7, 8, 6, 6, 9, 2, 8, 7, 1, 3, 2, 8, 5, 6, 3, 6, 1, 7, 2, 8, 1, 7, 9, 3, 4, 5, 2]
[5, 6, 1, 9, 2, 3, 8, 1, 8, 3, 4, 5, 7, 6, 2, 1, 9, 7, 8, 4, 6, 9, 2, 5, 4, 5, 3, 9, 7, 8, 6, 6, 9, 2, 8, 7, 1, 3, 2, 8, 5, 6, 3, 6, 1, 7, 2, 8, 1, 7, 9, 3, 4, 5, 2]
checkov flag:
:u$YBPf2pa]Dt4#QM^H4ic'j0`w2y{d-Zzo2%/n_s@+2<UW)e4AR;F.4=-qEkvC2
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK