Skip to main content

常用脚本

部分脚本来源于网络,需要的自取,不需要的不取

爆破多个压缩包CRC

#爆破多个压缩包的crc
#长度为4字节
import zipfile
import string
import binascii
path = 'D:\\IDM_download\\file_17\\out'#输入文件夹目录

crcs = [''] * 68#压缩包总个数
txts = [''] * 68#同上

for i in range(68):
file = path + str(i) + '.zip'
f = zipfile.ZipFile(file, 'r')
crcs[i] = f.getinfo('data.txt').CRC

dic = string.printable[:-6]
num = 0
for i in dic:
for j in dic:
for k in dic:
for l in dic:
s = i + j + k + l
c = binascii.crc32(s.encode('utf-8'))
for n in range(68):
if c == crcs[n]:
txts[n] = s
print('No.%d is %s' %(n, s))
num += 1
if num == 68:
print(txts)
print(''.join(txts))
break
else:
continue
break
else:
continue
break
else:
continue
break

自动读取CRC爆破图片高宽

import zlib
import struct
import binascii


file = 'out.png'
fr = open(file,'rb').read()
data = bytearray(fr[12:29])

#crc32key = eval(str(fr[29:33]).replace('\\x','').replace("b'",'0x').replace("'",''))
crc32key = struct.unpack('>I',fr[29:33])[0]&0xffffffff
print(crc32key)
#data = bytearray(b'\x49\x48\x44\x52\x00\x00\x01\xF4\x00\x00\x01\xF1\x08\x06\x00\x00\x00')
n = 4096
for w in range(n):
width = bytearray(struct.pack('>i', w))
for h in range(n):
height = bytearray(struct.pack('>i', h))
for x in range(4):
data[x+4] = width[x]
data[x+8] = height[x]
#print(data)
crc32result = zlib.crc32(data)
if crc32result == crc32key:
print(crc32key)
print(width,height)
print(data)
newpic = bytearray(fr)
for x in range(4):
newpic[x+16] = width[x]
newpic[x+20] = height[x]
fw = open(file+'.png','wb')
fw.write(newpic)
fw.close

压缩包名字解压密码为最外层压缩包

import zipfile
name = '0573'
while True:
fz = zipfile.ZipFile(name + '.zip', 'r')
fz.extractall(pwd=bytes(name, 'utf-8'))
name = fz.filelist[0].filename[0:4]
fz.close()

读取压缩包名字自动解压

import zipfile
import re
zipname = "E:\\网站搭建\\资源库\\"+"1.zip"
while True:
if zipname != "E:\\网站搭建\\资源库\\73168.zip":
ts1 = zipfile.ZipFile(zipname)
#print ts1.namelist()[0]
res = re.search('[0-9]*',ts1.namelist()[0])
print(res.group())
passwd = res.group()
ts1.extractall("E:\\网站搭建\\资源库",pwd=passwd.encode('ascii'))
zipname = "E:\\网站搭建\\资源库\\"+ts1.namelist()[0]
else:
print("find")

Adam7小图合成大图

from PIL import Image
from tqdm import tqdm
list = [(0,0,8,8),(4,0,8,8),(0,4,4,8),(2,0,4,4),(0,2,2,4),(1,0,2,2),(0,1,1,2)] #(起始横坐标,起始纵坐标,横向间隔,纵向间隔)
path = './small/'
w,h = Image.open(f'{path}flags_6.png').size
f = open(f'{path}flags_6.png','rb').read()
type = 0
ind = f.find(b'IHDR')
print(f[ind+13])
if(f[ind+13] == 0):
type = 'L'
elif(f[ind+13] == 2):
type = 'RGB'
elif(f[ind+13] == 6):
type = 'RGBA'
else:
print('暂不支持其他类型')
exit(0)
pic = Image.new(type,(w,h*2)) #此处判断高度未经过严格计算,因为不知道是h*2+1还是h*2,但出题人自己知道大小因此这里就不做额外的判断

for i in tqdm(range(7)):
img = Image.open(f'{path}flags_{str(i)}.png')
w_tmp,h_tmp = img.size
for j in range(h_tmp):
for k in range(w_tmp):
pic.putpixel((list[i][0]+k*list[i][2],list[i][1]+j*list[i][3]),img.getpixel((k,j)))
pic.save('out.png')

python2-base64隐写解密

b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
with open('flag.txt', 'rb') as f:
bin_str = ''
for line in f.readlines():
stegb64 = ''.join(line.split())
rowb64 = ''.join(stegb64.decode('base64').encode('base64').split())

offset = abs(b64chars.index(stegb64.replace('=', '')[-1]) - b64chars.index(rowb64.replace('=', '')[-1]))
equalnum = stegb64.count('=')

if equalnum:
bin_str += bin(offset)[2:].zfill(equalnum * 2)

print ''.join([chr(int(bin_str[i:i + 8], 2)) for i in xrange(0, len(bin_str), 8)])

BMP第1步-爆破宽度

import zlib
import struct
import binascii
import os


file = '11.bmp'
fr = open(file,'rb').read()
headdata = bytearray(fr[0:18])
widthdata = bytearray(fr[18:22])
heightdata = bytearray(fr[22:26])
remaindata = bytearray(fr[26::])

'''
print (headdata)
print('========================================================')
print (heightdata)
print('========================================================')
print (widthdata)
print('========================================================')
print (remaindata)
'''

n = 1000

h = 300

path=os.getcwd()
tmppath=path+'\\tmppic'
print(tmppath)

if os.path.exists(tmppath):
os.chdir(tmppath)
else:
os.mkdir(tmppath)
os.chdir(tmppath)

heightdata=h.to_bytes(4, 'little')


for w in range(1,n):
widthdata=w.to_bytes(4, 'little')

# print (widthdata)

newfile=headdata+widthdata+heightdata+remaindata
fw = open(str(w)+'.bmp','wb')
fw.write(newfile)
fw.close

BMP第二步爆破长度

import zlib
import struct
import binascii
import os


file = '11.bmp'
fr = open(file,'rb').read()
headdata = bytearray(fr[0:18])
widthdata = bytearray(fr[18:22])
heightdata = bytearray(fr[22:26])
remaindata = bytearray(fr[26::])

'''
print (headdata)
print('========================================================')
print (heightdata)
print('========================================================')
print (widthdata)
print('========================================================')
print (remaindata)
'''

n = 1000

w = 536

path=os.getcwd()
tmppath=path+'\\tmppic'
print(tmppath)

if os.path.exists(tmppath):
os.chdir(tmppath)
else:
os.mkdir(tmppath)
os.chdir(tmppath)

widthdata=w.to_bytes(4, 'little')


for h in range(1,n):
heightdata=h.to_bytes(4, 'little')

# print (widthdata)

newfile=headdata+widthdata+heightdata+remaindata
fw = open(str(h)+'.bmp','wb')
fw.write(newfile)
fw.close

爆破emoji-aes

# -*- codeing = utf-8 -*-
# @Time : 2021/12/28 17:53
# @Author : Mumuzi
# @File : burst_emoji_aes.py
# @Software : PyCharm

'''
其实和emoji-aes没啥关系,就替换成base64之后再爆破而已...
emmmm当然直接去调js也行,只是我不会
脚本中重要部分也是github有的,所以这题很简单
扒源码的时候注意到他是先小写再大写,正常base64表是先大写再小写的
'''

from tqdm import tqdm
from Crypto.Cipher import AES
import base64
from hashlib import md5
import string
import itertools

emojisInit = ["🍎", "🍌", "🏎", "🚪", "👁", "👣", "😀", "🖐", "ℹ", "😂", "🥋", "✉", "🚹", "🌉", "👌", "🍍", "👑", "👉", "🎤", "🚰", "☂", "🐍", "💧", "✖", "☀", "🦓", "🏹", "🎈", "😎", "🎅", "🐘", "🌿", "🌏", "🌪", "☃", "🍵", "🍴", "🚨", "📮", "🕹", "📂", "🛩", "⌨", "🔄", "🔬", "🐅", "🙃", "🐎", "🌊", "🚫", "❓", "⏩", "😁", "😆", "💵", "🤣", "☺", "😊", "😇", "😡", "🎃", "😍", "✅", "🔪", "🗒"]
table = string.ascii_lowercase+string.ascii_uppercase+string.digits+'+/='
table = list(table)

def unpad(data):
return data[:-(data[-1] if type(data[-1]) == int else ord(data[-1]))]

def bytes_to_key(data, salt, output=48):
# extended from https://gist.github.com/gsakkis/4546068
assert len(salt) == 8, len(salt)
data += salt
key = md5(data).digest()
final_key = key
while len(final_key) < output:
key = md5(key + data).digest()
final_key += key
return final_key[:output]

def decrypt(emo, passphrase):
#https://my.oschina.net/u/3021599/blog/3134709
bs64 = ''
for i in emo:
bs64 += table[emojisInit.index(i)]
encrypted = base64.b64decode(bs64)
assert encrypted[0:8] == b"Salted__"
salt = encrypted[8:16]
key_iv = bytes_to_key(passphrase, salt, 32+16)
key = key_iv[:32]
iv = key_iv[32:]
aes = AES.new(key, AES.MODE_CBC, iv)
return unpad(aes.decrypt(encrypted[16:]))

if __name__ == '__main__':
TABLE = string.ascii_lowercase+string.digits
emoji_enc = input('input your emoji_enc:')
for i in tqdm(itertools.product(''.join(i for i in TABLE), repeat= 6)):
passphrase = str(''.join(i)).encode('utf-8')
result = decrypt(emoji_enc,passphrase)
if(b'flag' in result):
print('text is :',result,'and key is :',passphrase)

cloacked-pixel爆破

from lsb import extract
import os
from tqdm import tqdm
'''
use py2
'''

hidden_img = 'ATM.png'#image file path
codebook = 'passwd.txt'#password path
passwd = open(codebook,'r').read().splitlines()

os.mkdir(hidden_img[:-4])

for i in tqdm(range(len(passwd))):
out_path = hidden_img[:-4]+'/'+passwd[i]+'.txt'
extract(hidden_img, out_path, passwd[i])

CRCcrack

#!/usr/bin/env python3
import sys
import os
import string
import collections

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='*')
parser.add_argument('--hex', action='append')
parser.add_argument('--dec', action='append')
parser.add_argument('--limit', type=int)
parser.add_argument('--compiler', default='g++')
parser.add_argument('--alphabet', type=os.fsencode, default=string.printable.encode())
args = parser.parse_args()

targets = collections.OrderedDict()
limit = 0
crcs = []

if args.limit:
limit = max(limit, args.limit)
if args.hex or args.dec:
if not args.limit:
parser.error('Limit of length not specified')

if args.hex:
for s in args.hex:
crc = int(s, 16)
targets[s] = crc
for l in range(args.limit + 1):
crcs += [( crc, l )]
if args.dec:
for s in args.dec:
crc = int(s)
targets[s] = crc
for l in range(args.limit + 1):
crcs += [( crc, l )]

if args.file:
print('reading zip files...', file=sys.stderr)
import zipfile
for zipname in args.file:
fh = zipfile.ZipFile(zipname)
for info in fh.infolist():
targets['%s / %s' % ( zipname, info.filename )] = ( info.CRC, info.file_size )
crcs += [( info.CRC, info.file_size )]
limit = max(limit, info.file_size)
print('file found: %s / %s: crc = 0x%08x, size = %d' % (zipname, info.filename, info.CRC, info.file_size), file=sys.stderr)

if not crcs:
parser.error('No CRCs given')

# compiling c++ in python script is the easy way to have the both a good interface and better speed
code = ''
code += r'''
#include <cstdio>
#include <vector>
#include <array>
#include <string>
#include <set>
#include <cstdint>
#include <cctype>
#define repeat(i,n) for (int i = 0; (i) < (n); ++(i))
using namespace std;
uint32_t crc_table[256];
void make_crc_table() {
repeat (i, 256) {
uint32_t c = i;
repeat (j, 8) {
c = (c & 1) ? (0xedb88320 ^ (c >> 1)) : (c >> 1);
}
crc_table[i] = c;
}
}
const uint32_t initial_crc32 = 0xffffffff;
uint32_t next_crc32(uint32_t c, char b) {
return crc_table[(c ^ b) & 0xff] ^ (c >> 8);
}
const uint32_t mask_crc32 = 0xffffffff;
const char alphabet[] = { ''' + ', '.join(map(str, args.alphabet)) + r''' };
const int limit = ''' + str(limit) + r''';
array<set<uint32_t>, limit+1> crcs;
string stk;
void dfs(uint32_t crc) {
if (crcs[stk.length()].count(crc ^ mask_crc32)) {
fprintf(stderr, "crc found: 0x%08x: \"", crc ^ mask_crc32);
for (char c : stk) fprintf(stderr, isprint(c) && (c != '\\') ? "%c" : "\\x%02x", c);
fprintf(stderr, "\"\n");
printf("%08x ", crc ^ mask_crc32);
for (char c : stk) printf(" %02x", c);
printf("\n");
}
if (stk.length() < limit) {
for (char c : alphabet) {
stk.push_back(c);
dfs(next_crc32(crc, c));
stk.pop_back();
}
}
}
int main() {
'''
for crc, size in crcs:
code += ' crcs[' + str(size) + '].insert(' + hex(crc) + ');\n'
code += r'''
make_crc_table();
dfs(initial_crc32);
return 0;
}
'''

import tempfile
import subprocess
with tempfile.TemporaryDirectory() as tmpdir:
cppname = os.path.join(tmpdir, 'a.cpp')
with open(cppname, 'w') as fh:
fh.write(code)
binname = os.path.join(tmpdir, 'a.out')
print('compiling...', file=sys.stderr)
p = subprocess.check_call([args.compiler, '-std=c++11', '-O3', '-o', binname, cppname])
print('searching...', file=sys.stderr)
p = subprocess.Popen([binname], stdout=subprocess.PIPE)
output, _ = p.communicate()

print('done', file=sys.stderr)
print(file=sys.stderr)
result = collections.defaultdict(list)
for line in output.decode().strip().split('\n'):
crc, *val = map(lambda x: int(x, 16), line.split())
result[( crc, len(val) )] += [ bytes(val) ]
for key, crc in targets.items():
for s in result[crc]:
print('%s : %s' % (key, repr(s)[1:]))

deepsound2john

#!/usr/bin/env python3
'''
deepsound2john extracts password hashes from audio files containing encrypted
data steganographically embedded by DeepSound (http://jpinsoft.net/deepsound/).
This method is known to work with files created by DeepSound 2.0.
Input files should be in .wav format. Hashes can be recovered from audio files
even after conversion from other formats, e.g.,
ffmpeg -i input output.wav
Usage:
python3 deepsound2john.py carrier.wav > hashes.txt
john hashes.txt
This software is copyright (c) 2018 Ryan Govostes <[email protected]>, and
it is hereby released to the general public under the following terms:
Redistribution and use in source and binary forms, with or without
modification, are permitted.
'''

import logging
import os
import sys
import textwrap


def decode_data_low(buf):
return buf[::2]

def decode_data_normal(buf):
out = bytearray()
for i in range(0, len(buf), 4):
out.append((buf[i] & 15) << 4 | (buf[i + 2] & 15))
return out

def decode_data_high(buf):
out = bytearray()
for i in range(0, len(buf), 8):
out.append((buf[i] & 3) << 6 | (buf[i + 2] & 3) << 4 \
| (buf[i + 4] & 3) << 2 | (buf[i + 6] & 3))
return out


def is_magic(buf):
# This is a more efficient way of testing for the `DSCF` magic header without
# decoding the whole buffer
return (buf[0] & 15) == (68 >> 4) and (buf[2] & 15) == (68 & 15) \
and (buf[4] & 15) == (83 >> 4) and (buf[6] & 15) == (83 & 15) \
and (buf[8] & 15) == (67 >> 4) and (buf[10] & 15) == (67 & 15) \
and (buf[12] & 15) == (70 >> 4) and (buf[14] & 15) == (70 & 15)


def is_wave(buf):
return buf[0:4] == b'RIFF' and buf[8:12] == b'WAVE'


def process_deepsound_file(f):
bname = os.path.basename(f.name)
logger = logging.getLogger(bname)

# Check if it's a .wav file
buf = f.read(12)
if not is_wave(buf):
global convert_warn
logger.error('file not in .wav format')
convert_warn = True
return
f.seek(0, os.SEEK_SET)

# Scan for the marker...
hdrsz = 104
hdr = None

while True:
off = f.tell()
buf = f.read(hdrsz)
if len(buf) < hdrsz: break

if is_magic(buf):
hdr = decode_data_normal(buf)
logger.info('found DeepSound header at offset %i', off)
break

f.seek(-hdrsz + 1, os.SEEK_CUR)

if hdr is None:
logger.warn('does not appear to be a DeepSound file')
return

# Check some header fields
mode = hdr[4]
encrypted = hdr[5]

modes = {2: 'low', 4: 'normal', 8: 'high'}
if mode in modes:
logger.info('data is encoded in %s-quality mode', modes[mode])
else:
logger.error('unexpected data encoding mode %i', modes[mode])
return

if encrypted == 0:
logger.warn('file is not encrypted')
return
elif encrypted != 1:
logger.error('unexpected encryption flag %i', encrypted)
return

sha1 = hdr[6:6+20]
print('%s:$dynamic_1529$%s' % (bname, sha1.hex()))


if __name__ == '__main__':
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='store_true')
parser.add_argument('files', nargs='+', metavar='file',
type=argparse.FileType('rb', bufsize=4096))
args = parser.parse_args()

if args.verbose:
logging.basicConfig(level=logging.INFO)
else:
logging.basicConfig(level=logging.WARN)

convert_warn = False

for f in args.files:
process_deepsound_file(f)

if convert_warn:
print(textwrap.dedent('''
---------------------------------------------------------------
Some files were not in .wav format. Try converting them to .wav
and try again. You can use: ffmpeg -i input output.wav
---------------------------------------------------------------
'''.rstrip()), file=sys.stderr)

MTP一次多密

#密文为十六进制字符串,应该先将其处理
ciphertexts = [
"315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e",
"234c02ecbbfbafa3ed18510abd11fa724fcda2018a1a8342cf064bbde548b12b07df44ba7191d9606ef4081ffde5ad46a5069d9f7f543bedb9c861bf29c7e205132eda9382b0bc2c5c4b45f919cf3a9f1cb74151f6d551f4480c82b2cb24cc5b028aa76eb7b4ab24171ab3cdadb8356f",
"32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb",
"32510ba9aab2a8a4fd06414fb517b5605cc0aa0dc91a8908c2064ba8ad5ea06a029056f47a8ad3306ef5021eafe1ac01a81197847a5c68a1b78769a37bc8f4575432c198ccb4ef63590256e305cd3a9544ee4160ead45aef520489e7da7d835402bca670bda8eb775200b8dabbba246b130f040d8ec6447e2c767f3d30ed81ea2e4c1404e1315a1010e7229be6636aaa",
"3f561ba9adb4b6ebec54424ba317b564418fac0dd35f8c08d31a1fe9e24fe56808c213f17c81d9607cee021dafe1e001b21ade877a5e68bea88d61b93ac5ee0d562e8e9582f5ef375f0a4ae20ed86e935de81230b59b73fb4302cd95d770c65b40aaa065f2a5e33a5a0bb5dcaba43722130f042f8ec85b7c2070",
"32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4",
"32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba764896cf606ef40c04afe1ac0aa81dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce",
"315c4eeaa8b5f8bffd11155ea506b56041c6a00c8a08854dd21a4bbde54ce56801d943ba708b8a3574f40c00fff9e00fa1439fd0654327a3bfc860b92f89ee04132ecb9298f5fd2d5e4b45e40ecc3b9d59e9417df7c95bba410e9aa2ca24c5474da2f276baa3ac325918b2daada43d6712150441c2e04f6565517f317da9d3",
"271946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027",
"466d06ece998b7a2fb1d464fed2ced7641ddaa3cc31c9941cf110abbf409ed39598005b3399ccfafb61d0315fca0a314be138a9f32503bedac8067f03adbf3575c3b8edc9ba7f537530541ab0f9f3cd04ff50d66f1d559ba520e89a2cb2a83",
"32510ba9babebbbefd001547a810e67149caee11d945cd7fc81a05e9f85aac650e9052ba6a8cd8257bf14d13e6f0a803b54fde9e77472dbff89d71b57bddef121336cb85ccb8f3315f4b52e301d16e9f52f904"
]

NUM_CIPHER = len(ciphertexts)#NUM_CIPHER=11
THRESHOLD_VALUE = 7#如果两两异或的结果为字母数大于7次,就认为该字符为空格,该值更改会影响最终结果

def strxor(a, b):
#两个字符串的异或
if len(a) > len(b):
# 形成二元组,异或,返回新字符串
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a[:len(b)], b)])
else:
return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b[:len(a)])])

def letter_position(s):
#返回给定字符串中给定字母的位置
position = []
for idx in range(len(s)):
#考虑到空格异或为0的情况可能较多
if (s[idx] >= 'A' and s[idx] <= 'Z') or (s[idx] >= 'a' and s[idx] <= 'z') or s[idx] == chr(0):
position.append(idx)
return position

def find_space(cipher):
#寻找空字符
space_position = {}
space_possible = {}
#双重循环,每一条密文均与其他密文异或
for cipher_idx_1 in range(NUM_CIPHER):
space_xor = []#用于保存可能空格符对应的位置
c = ''.join([chr(int(d, 16)) for d in [cipher[cipher_idx_1][i:i + 2] for i in range(0, len(cipher[cipher_idx_1]), 2)]])
for cipher_idx_2 in range(NUM_CIPHER):
#将十六进制字符串处理成对应ascii字符(每两个字符代表一个ascii符号)
e = ''.join([chr(int(d, 16)) for d in [cipher[cipher_idx_2][i:i+2] for i in range(0, len(cipher[cipher_idx_2]), 2)]])
plain_xor = strxor(c, e)
if cipher_idx_2 != cipher_idx_1:
# 记录明文中可能空格符的位置
space_xor.append(letter_position(plain_xor))
space_possible[cipher_idx_1] = space_xor #形成三维列表,新列表为11*10*n

#进一步判断已记录的位置是否为空字符,其准确性受到文本数量的影响
for cipher_idx_1 in range(NUM_CIPHER):
spa = []
for position in range(400):
count = 0
for cipher_idx_2 in range(NUM_CIPHER - 1):
if position in space_possible[cipher_idx_1][cipher_idx_2]:
count += 1
if count > THRESHOLD_VALUE: # 如果异或后字母出现次数大于7次,认为明文中此处为空格
spa.append(position)
space_position[cipher_idx_1] = spa #构成二维列表,11 * n
return space_position

#计算获得对应密钥Key
def calculate_key(cipher):
key = [0] * 200 #存放key
space = find_space(cipher)
#print(space)
for cipher_idx_1 in range(NUM_CIPHER):
for position in range(len(space[cipher_idx_1])):
idx = space[cipher_idx_1][position] * 2 #十六进制,用2位表示
a = cipher[cipher_idx_1][idx] + cipher[cipher_idx_1][idx + 1]
key[space[cipher_idx_1][position]] = int(a ,16) ^ ord(' ') # 计算密钥,获得结果十进制(ascii码)

key_str = ""#空串用于存放密钥
for k in key:
key_str += chr(k)#转化为
return key_str #获得密钥串

result = ""
key = calculate_key(ciphertexts)
key_hex = ''.join([hex(ord(c)).replace('0x', '') for c in key])#十六进制key
print("key=",key)
print("key_hex=",key_hex)

# f = ''.join([chr(int(d, 16)) for d in [ciphertexts[10][i:i+2] for i in range(0, len(ciphertexts[10]), 2)]])
# for letter in strxor(f,key):
# if (letter>=' ' and letter<='~ '):#打印从32-126的可见字符
# result+=letter
# else:
# result+='0'#不可打印字符用0代替,以区别空格符
# print(result)


#打印所有密文对应的明文
for j in range(11):
f = ''.join([chr(int(d, 16)) for d in [ciphertexts[j][i:i + 2] for i in range(0, len(ciphertexts[j]), 2)]])
for letter in strxor(f,key):
if (letter>=' ' and letter<='~ '):
result+=letter
else:
result+='0'
print(result)
result = '' #将result清空,再次使用


RSA常见一把梭

# coding:utf-8
import gmpy2, libnum
from Crypto.PublicKey import RSA
from Crypto.Util.number import bytes_to_long


def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)


def extended_gcd(a, b):
x, y = 0, 1
lastx, lasty = 1, 0
while b:
a, (q, b) = b, divmod(a, b)
x, lastx = lastx - q * x, x
y, lasty = lasty - q * y, y
return (lastx, lasty, a)


def CRT(items): # 中国剩余定理
N = 1
for a, n in items:
N *= n
result = 0
for a, n in items:
m = N // n
r, s, d = extended_gcd(n, m)
if d != 1:
N = N // n
continue
result += a * s * m
return result % N, N


def p_q_e():
p = int(input("p="))
q = int(input("q="))
e = int(input("e="))
c = int(input("c="))
phi = (p - 1) * (q - 1)
n = p * q
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print("明文:", libnum.n2s(m))


def Common_Modulus():
n = int(input("n="))
e1 = int(input("e1="))
c1 = int(input("c1="))
e2 = int(input("e2="))
c2 = int(input("c2="))

s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
# 求模反元素
if s1 < 0:
s1 = - s1
c1 = gmpy2.invert(c1, n)
elif s2 < 0:
s2 = - s2
c2 = gmpy2.invert(c2, n)

m = pow(c1, s1, n) * pow(c2, s2, n) % n
print("明文:", libnum.n2s(m))


def Small_plaintext_e3():
e = int(input("e="))
n = int(input("n="))
c = int(input("c="))
for k in range(200000000):
if gmpy2.iroot(c + n * k, e)[1] == 1:
m = gmpy2.iroot(c + n * k, e)[0]
print("明文:", libnum.n2s(m))
break


def n_e_dp():
n = int(input("n="))
e = int(input("e="))
dp = int(input("dp="))
c = int(input("c="))
for i in range(1, 65538):
if (dp * e - 1) % i == 0:
if n % (((dp * e - 1) // i) + 1) == 0:
p = ((dp * e - 1) // i) + 1
q = n // p
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi) % phi
print(libnum.n2s(pow(c, d, n)))


def N2_equal_P():
n1 = int(input("n1="))
n2 = int(input("n2="))
e1 = int(input("e1="))
e2 = int(input("e2="))
c1 = int(input("c1="))
c2 = int(input("c2="))
p = gmpy2.gcd(n1, n2)
# print(p)
q1 = n1 // p
q2 = n2 // p
phi_1 = (p - 1) * (q1 - 1)
phi_2 = (p - 1) * (q2 - 1)
d1 = gmpy2.invert(e1, phi_1)
d2 = gmpy2.invert(e2, phi_2)
print("m1:", libnum.n2s(pow(c1, d1, n1)))
print("m2:", libnum.n2s(pow(c2, d2, n2)))


def Prime_3():
p = int(input("p="))
q = int(input("q="))
r = int(input("r="))
e = int(input("e="))
c = int(input("c="))
s = (p - 1) * (q - 1) * (r - 1)
d = (gmpy2.invert(e, s))
n = p * q * r
m = pow(c, d, n)
print("明文:", libnum.n2s(m))


def RSA_File():
public_name = input("请输入公钥文件名(没有直接回车):")
flag_name = input("请输入加密文件名:")
private_name = input("请输入私钥文件名(没有直接回车):")
with open(flag_name, 'rb') as f:
c = bytes_to_long(f.read())
if private_name == "":
pass
else:
with open(private_name, 'r') as private:
Key = RSA.importKey(private.read())
n, e, d, p, q = Key.n, Key.e, Key.d, Key.p, Key.q
m = pow(c, d, n)
print("明文:", libnum.n2s(m))
return
with open(public_name, 'r') as public:
key = RSA.importKey(public.read())
n, e = key.n, key.e

print("n=", n)
print("e=", e)
print("c=", c)


def next_prime():
n = int(input("n="))
e = int(input("e="))
c = int(input("c="))
i = gmpy2.isqrt(n)
p, q = 0, 0
while True:
if n - (i * (n // i)) == 0:
p = i
q = n // i
break
i += 1
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print("明文:", libnum.n2s(m))


def Broadcast():
print('n,e,c由文件导入,请确保格式为[{"c": , "e": , "n":}]')
print("不同组用逗号隔开,如[{},{}]")
file_name = input("请输入文件名:")
with open(file_name, 'r') as f:
f = f.read()
sessions = eval(f)
data = []
for session in sessions:
e = session['e']
n = session['n']
msg = session['c']
data = data + [(msg, n)]
print("Please wait, performing CRT")
x, n = CRT(data)
e = session['e']
m = gmpy2.iroot(x, e)[0]
print("明文:", libnum.n2s(m))


if __name__ == "__main__":
print("1.已知p,q,e")
print("2.共模攻击")
print("3.小明文攻击,e一般为3")
print("4.已知n,e,dp")
print("5.模不互素,求出共因子p")
print("6.三个素数的RSA")
print("7.读取RSA公钥文件,私钥文件和密文")
print("8.p,q相近")
print("9.低加密指数广播攻击")
x = input("请选择解密方法:")

if x == '1':
p_q_e()
if x == '2':
Common_Modulus()
if x == '3':
Small_plaintext_e3()
if x == '4':
n_e_dp()
if x == '5':
N2_equal_P()
if x == '6':
Prime_3()
if x == '7':
RSA_File()
if x == '8':
next_prime()
if x == '9':
Broadcast()

Vigenere加密(基于词频分析,可异或)

from itertools import *
from string import printable
alphabet = list(range(256))
LETTER_FREQUENCY = {
' ': 0.25000,
'e': 0.12702,
't': 0.09056,
'a': 0.08167,
'o': 0.07507,
'i': 0.06966,
'n': 0.06749,
's': 0.06327,
'h': 0.06094,
'r': 0.05987,
'd': 0.04253,
'l': 0.04025,
'c': 0.02782,
'u': 0.02758,
'm': 0.02406,
'w': 0.02360,
'f': 0.02228,
'g': 0.02015,
'y': 0.01974,
'p': 0.01929,
'b': 0.01492,
'v': 0.00978,
'k': 0.00772,
'j': 0.00153,
'x': 0.00150,
'q': 0.00095,
'z': 0.00074
}
def IndCo(s):
N = len(s)
frequency = [s.count(c) for c in alphabet]
return sum(i**2 - i for i in frequency) / (N**2 - N)
def CalKeyLength(s):
res = []
for kl in range(2, 38):
subs = [s[i::kl] for i in range(kl)]
if sum(IndCo(si) for si in subs) / kl > 0.06:
if all(map(lambda x: kl % x, res)):
res.append(kl)
return res
def score(s):
score = 0
for c in s.lower():
if c in LETTER_FREQUENCY:
score += LETTER_FREQUENCY[c]
return score
# def RecoverKey(ct, kl):
# keyword = ''
# subs = [ct[i::kl] for i in range(kl)]
# for s in subs:
# frequency = [s.count(c) for c in alphabet]
# most_fqc = max(frequency)
# keyword += alphabet[(frequency.index(most_fqc) - 4) % len(alphabet)]
# return keyword
def RecoverKey(ct, kl):
key = b''
subs = [ct[i::kl] for i in range(kl)]
for s in subs:
scores = []
for xor in range(256):
xored_s = ''.join(chr(c ^ xor) for c in s)
if all(c in printable for c in xored_s):
scores.append((xor, score(xored_s)))
key += bytes([max(scores, key=lambda x: x[1])[0]])
return key
def Vigenere_dec(cipher, key):
keyCircle = cycle(key)
pt = ''
for c in cipher:
pt += chr(c ^ next(keyCircle))
return pt
# def Vigenere_dec(ct, k):
# shifts = cycle(alphabet.index(c) for c in k)
# pt = ''
# for c in ct.lower():
# if c not in alphabet:
# next(shifts)
# pt += c
# continue
# pt += alphabet[(alphabet.index(c) - next(shifts)) % len(alphabet)]
# return pt
def main():
cipher = b'G\x05!\x02X\x13!\x10\tO\x06\x14g;\x10\x01m?+OB\x1e0\x0cP\x1b\x07\x1fg?\x0e\x10 36\x1bFV:\x04Pe\x0eZ7;\x0b\x1b9?6\x08\x15\x19\'B\x14\x1d\x0e\r.4\x05U/74\x0e[\x150B\x15\x0e\x0c\x12g5\x16\x1d($xeZ\x03!LP;\x07\x134z\x01\x1a8:<OW\x13u\x16\x18\nO\x15%0\x07\x169%x\x1b]\x138\x11\x15\x03\x19\x1f4vB\x7f/#,O\\\x02u\x01\x11\x01O\x1b+)\rU?34\x0eA\x13u\x16\x1fO\x0c\x15+5\x10\x06m76\x0b\x15|:\x16\x18\n\x1dZ$5\x0f\x05"%1\x1b\\\x19;\x03\x1cO\x1b\x1f$2\x0c\x1c<#=\x1c\x1b|\x0c\r\x05O\x02\x1b>z\x0c\x1a9v*\nT\x1a<\x18\x15O\x06\x0ekz\x00\x009v!\x00@\x04u\x00\x02\x0e\x06\x14gP\x0b\x06m4-\x1cLV"\r\x02\x04\x06\x14 z\x00\x10%?6\x0b\x15\x02=\x07P\x1c\x0c\x1f)?\x11U99x\x1cP\x13>Bz\x00\x1a\x0eg)\x1b\x18 3,\x1dLV"\n\x15\x01O\x03(/B\x19"93OT\x02u\x03P\x1f\x0e\x13).\x0b\x1b*xxea\x1e0\x10\x15O\x0e\x08"z\x11\x10;3*\x0eYV\'\x07\x11\x1c\x00\x144z\x04\x1a?v,\x07\\\x05{B$\x07\nZM<\x0b\x07>"x\x06FV!\n\x11\x1bO\r"}\x10\x10m>9\x1dQ["\x0b\x02\n\x0bZ35B\x19"93OS\x19\'Bz\x06\x1bTg\x15\x17\x07m76\x0c\\\x13;\x16P\x0e\x01\x19")\x16\x1a?%x\x02T\x0fu\x0c\x1f\x1bO\x12&,\x07U%7<O?\x17u\x0c\x11\x02\nZ!5\x10U$"tOW\x03!B\x04\x07\n\x03g1\x0c\x10:v,\x07T\x02u\x16\x18\n\x06\x08gP\r\x02#v:\x00Q\x1f0\x11P\x18\n\x08"z\x00\x14>?;\x0eY\x1a,B\x03\x16\x02\x17".\x10\x1c.74C\x15\x17&Bz\x18\n\x08"z\x16\x1d"%=OZ\x10u\x12\x1f\x1b\n\x1433\x03\x19m&*\nQ\x17!\r\x02\x1cO\x155z\x12\x07(/vO?"=\x07\x02\n\t\x155?NU9>1\x1c\x15\x154\x0f\x15O\x06\x14g2\x03\x1b)/x\x18]\x13!\n\x15\x1dOp$2\r\x1a>?6\x08\x15\x17u\x0f\x11\x1b\nVg9\x03\x01.>1\x01RV1\x0b\x1e\x01\n\x08g5\x10UG7.\x00\\\x12<\x0c\x17O\r\x1f.4\x05U"8x\x1b]\x13u\x0f\x15\x01\x1aZ(<B\x14m%6\x0eG\x1a<\x0c\x17COp//\x0c\x12?/x\x1fT\x15>B\x1f\tO\r(6\x14\x10>v7\x1d\x15\x140\x03\x02\x1cNp\x13;\t\x10m7x\x03Z\x19>B\x11\x1bO\x03(/\x10U+7;\n\x15\x1f;B\x04\x07\nZ*3\x10\x07"$xeT\x181B\x19\x02\x0e\x1d.4\x07U,v4\x06[\x13u\x11\x04\x1d\x0e\x13 2\x16U)9/\x01\x15\x02=\x07Pe\x02\x13#>\x0e\x10cv\x01\x00@Q9\x0eP\x1c\n\x1fg8\r\x01%v+\x06Q\x13&B\x1f\tO\x03(/\x10UG09\x0cPV4\x10\x15O\x1f\x08".\x16\x0cm%!\x02X\x13!\x10\x19\x0c\x0e\x16iz6\x1d$%x\x06FV_\t\x1e\x00\x18\x14g;\x11U/?4\x0eA\x13\'\x03\x1cO\x1c\x03*7\x07\x01?/x\x0e[\x12u\x0b\x04H\x1cZM-\n\x10?3x\rZ\x02=B\x03\x06\x0b\x1f4z\x07\x1c9>=\x1d\x15\x05<\x06\x15O\x00\x1cg.\n\x1c>vR\x0b\\\x00<\x06\x19\x01\x08Z+3\x0c\x10m7(\x1fP\x17\'B\x1d\x00\x1d\x1fg5\x10U!3+\x1c\x15\x02=\x07P\x1c\x0e\x17"th&"v0\nG\x13u\x0b\x03O\x1b\x12"z\x04\x19,1bO?\x1e2\x03\x1d\n\x14"w(=\x1cx{90@%f\x04%^DN)>F\x13\x18\x186\x16j5d\x128\\\x1d\x07M'
# cipher = b''.join(bytes([c - 1]) for c in cipher)
kls = CalKeyLength(cipher)
print(f"All probable key length: {kls}")
for kl in kls:
key = RecoverKey(cipher, kl)
print(f"Key: {key}")
print(Vigenere_dec(cipher, key))
if __name__ == '__main__':
main()

爆破base64大小写

import base64

text = 'ZMXHZ3TCDXI1DF9ZMF9LEN0=' #这里输入待解密文


def all_possible(text):
res=[""]
for i in text:
if not i.isalpha():
for j in range(len(res)):
res[j] += i
else:
for k in range(len(res)):
tmp = res[k]
res[k] += i.lower()
res.append(tmp + i.upper())
return res

def baopo():
k = all_possible(text)
res = []
for i in k:
try:
f = base64.b64decode(i + '').decode("utf-8")
if(f.isprintable()):
res.append(f)
except:
pass

for i in res:
print(i)
print("[*]一共解出{0}个".format(len(res)))

baopo()

冰蝎xor解密-php

<?php
$key1="8dddd282f7b5125bLbptYjdmMWI4ZketfMqs+Pt4UU45UAFSyKkfUx0RSxrD/S6FNWbN6MfnLmIzYw==6b1ce45ad828e150";
//直接使用encode方法
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}

$key='421eb7f1b8e4b3cf';
$str=substr($key1, 16);
echo $str;
echo PHP_EOL;
$str2=substr($str,0,-16);
echo $str2;
echo PHP_EOL;
$str3=gzdecode(encode(base64_decode($str2),$key));
//gzdecode(encode(base64_decode($key1),$key))
echo $str3;
?>

解压zip rar targz套娃

import zipfile
import rarfile
import os
import tarfile

while True:
dirs = os.listdir('./')
files = dirs[1]
fs = open(files, 'rb').read()
if fs[:2] == b'PK':
zipf = zipfile.ZipFile(files, 'r')
zipf.extractall()
zipf.close()
os.remove(files)
elif fs[:3] == b'Rar':
rarf = rarfile.RarFile(files, 'r')
rarf.extractall()
rarf.close()
os.remove(files)
else:
t = tarfile.open(files)
t.extractall(path='.')
t.close()
os.remove(files)

猫脸变换

import cv2
from numba import njit #编译
import numpy as np

@njit()
def arnold_encode(image, shuffle_times, a, b):
""" Arnold shuffle for rgb image
Args:
image: input original rgb image
shuffle_times: how many times to shuffle
Returns:
Arnold encode image
"""
# 1:创建新图像
arnold_image = np.zeros(shape=image.shape)

# 2:计算N
h, w = image.shape[0], image.shape[1]
N = h # 或N=w

# 3:遍历像素坐标变换
for time in range(shuffle_times):
for ori_x in range(h):
for ori_y in range(w):
# 按照公式坐标变换
new_x = (1 * ori_x + b * ori_y) % N
new_y = (a * ori_x + (a * b + 1) * ori_y) % N

arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :]
image = arnold_image

return arnold_image


def arnold_decode(image, shuffle_times, a, b):
""" decode for rgb image that encoded by Arnold
Args:
image: rgb image encoded by Arnold
shuffle_times: how many times to shuffle
Returns:
decode image
"""
# 1:创建新图像
decode_image = np.zeros(shape=image.shape,dtype=int)

# 2:计算N
h, w = image.shape[0], image.shape[1]
N = h # 或N=w

# 3:遍历像素坐标变换
for time in range(shuffle_times):
for ori_x in range(h):
for ori_y in range(w):
# 按照公式坐标变换
new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % N
new_y = ((-a) * ori_x + ori_y) % N
decode_image[new_x, new_y, :] = image[ori_x, ori_y, :]

image = decode_image
return decode_image

img = cv2.imread("2.png") #变换的图片
a = 9
b = 39
st = 1
pic = arnold_decode(img,st,a,b)
cv2.imwrite('flag.png',pic) #保存得到的图片

#得到的宽和高有可能会和出题人的是反的哦

无文件头IHDR但IDAT正确可得宽高还原

import os,zlib,re,sys
import struct
from PIL import Image
from Crypto.Util.number import *
#考虑逐行和隔行扫描2种情况
file=r'playball.png'

fr=open(file,'rb').read()
path=os.getcwd()
def chdir(mypath):
tmppath=path+mypath
print(tmppath)
if os.path.exists(tmppath):
os.chdir(tmppath)
else:
os.mkdir(tmppath)
os.chdir(tmppath)

chunckid=[b'IHDR',b'PLTE',b'IDAT',b'IEND',b'cHRM',b'gAMA',b'iCCP',b'sBIT',b'sRGB',b'bKGD',b'hIST',b'tRNS',b'pHYs',b'sPLT',b'tIME',b'iTXt',b'tEXt',b'zTXt']
chuncks=[]
i=4
while i<len(fr):
if fr[i:i+4] in chunckid:
try:
datalen,dataname=struct.unpack(">I4s",fr[i-4:i+4])
dataformat='>I4s'+str(datalen)+'s'+'4s'
datalen,dataname,data,datacrc=struct.unpack(dataformat,fr[i-4:i-4+8+datalen+4])
realcrc=zlib.crc32(dataname+data).to_bytes(4,'big')
if realcrc!=datacrc:
datacrc=realcrc
print(dataname,'crc32 fixed')
print(datalen,bytes.decode(dataname,encoding='utf-8'),hex(int.from_bytes(datacrc,'big')))
chuncks.append(fr[i-4:i-4+8+datalen]+realcrc)
i=i+8+datalen+4 #最少加一,防止出现iend
except: #防止不能解析的结构体中出现png chunckid的关键字,指针直接指向下一个。
i=i+1
continue
else:
i=i+1

for chk in chuncks: #直接丢弃IHDR头部
if chk[4:8] == b'IHDR':
chuncks.remove(chk)

idat=[tmp for tmp in chuncks if tmp[4:8]==b'IDAT']
blocks=[tmp[8:int.from_bytes(tmp[:4],'big')+8] for tmp in chuncks if tmp[4:8]==b'IDAT']
blocks=b''.join(blocks) #组合数据
data=zlib.decompressobj().decompress(blocks) #解码zlib得到像素(含filter)
open('mytest.idat','wb').write(data)
#数组,分别为colortype,colortype对应颜色种类所占通道数,该colortype通道允许的字节位数bits(色深)
bt_ch_1=[(2,3,8),(2,3,16), \
(6,4,8),(6,4,16), \
(4,2,8),(4,2,16), \
(0,1,1),(0,1,2),(0,1,4),(0,1,8),(0,1,16)]
bt_ch_2=[(2,3,8),(2,3,16), \
(6,4,8),(6,4,16)]
bt_ch_22=[(2,3,8),(6,4,8)]
bt_ch_3=[(3,1,8),(3,1,4),(3,1,2),(3,1,1)]
bt_ch_33=[(3,1,8)]
####################################################################################################################################
def crack_no_inter(bt_ch,width):
chdir('\\PNG_no_Interlace')
interlace=b'\x00' #首先考虑逐行扫描的情况
for w in range (1,width):
print('percent: {:.2f}%'.format(w/width*100))
for i in bt_ch:
colortype=i[0]
colorchannel=i[1]
bits=i[2]
data1=[t for t in data[::(bits*colorchannel*w//8+1)]] #以1个字节的filter头加上扫描线来切片
# data2=[data[i:i+(bits*colorchannel*w//8+1)] for i in range(0,len(data),bits*colorchannel*w//8+1) ] #扫描线数据
if set(data1).issubset(b'\x00\x01\x02\x03\x04') and len(data1)!=1: #如果每片的头部合集都在,0,1,2,3,4以内,就说明切片可能正确,得到宽度
# data2=[data[i:i+(bits*colorchannel*w//8+1)] for i in range(0,len(data),bits*colorchannel*w//8+1) ]
# res.append((colortype,colorchannel,bits,w,len(data1)))
print(w,len(data1),colortype,':',colorchannel,':',bits)
head=b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52'+w.to_bytes(4,'big')+len(data1).to_bytes(4,'big')+bits.to_bytes(1,'big')+colortype.to_bytes(1,'big')+b'\x00\x00'+interlace
headcrc=zlib.crc32(head[12:])
head=head+headcrc.to_bytes(4,'big')
with open(str(w)+'X'+str(len(data1))+'_'+str(colortype)+'_'+str(colorchannel)+'_'+str(bits)+'.png','wb') as fw:
fw.write(head+b''.join(chuncks))
elif len(data1)==1:
break
print('逐行扫描完成,请在PNG_no_Interlace目录下查看是否有正常显示的图片,下面开始隔行扫描,先考虑常见的色彩模式(非灰度),分辨率在2000x2000以内')
print(150*'↓')
####################################################################################################################################
def crack_adam7_inter(bt_ch,width,height):
chdir('\\PNG_Adam7_Interlace')
interlace=b'\x01' #考虑隔行扫描的情况
for w in range(1,width):
print('percent: {:.2f}%'.format(w/width*100))
for h in range(1,height):
for i in bt_ch:
w1=[i for i in range(w)]
h1=[i for i in range(h)]
colortype=i[0]
colorchannel=i[1]
bits=i[2] #7次扫描,按照那个8x8方阵进行7次扫描生成7个小图,然后拼接成idat,如果长度刚好和zlib decompress后的数据块data长度相等,判断宽高正确
len_1=(len(w1[0::8])*bits*colorchannel//8+1)*len(h1[0::8]) \
+(len(w1[4::8])*bits*colorchannel//8+1)*len(h1[0::8]) \
+(len(w1[0::4])*bits*colorchannel//8+1)*len(h1[4::8]) \
+(len(w1[2::4])*bits*colorchannel//8+1)*len(h1[0::4]) \
+(len(w1[0::2])*bits*colorchannel//8+1)*len(h1[2::4]) \
+(len(w1[1::2])*bits*colorchannel//8+1)*len(h1[0::2]) \
+(len(w1[0::1])*bits*colorchannel//8+1)*len(h1[1::2])
if len_1==len(data):
print(w,h,colortype,colorchannel,bits)
head=b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52'+w.to_bytes(4,'big')+h.to_bytes(4,'big')+bits.to_bytes(1,'big')+colortype.to_bytes(1,'big')+b'\x00\x00'+interlace
headcrc=zlib.crc32(head[12:])
head=head+headcrc.to_bytes(4,'big')
with open(str(w)+'X'+str(h)+'_'+str(colortype)+'_'+str(colorchannel)+'_'+str(bits)+'.png','wb') as fw:
fw.write(head+b''.join(chuncks))
####################################################################################################################################

chks=[i[4:8] for i in chuncks]
if b'PLTE' in chks:
crack_no_inter(bt_ch_3,20001)
crack_adam7_inter(bt_ch_33,2001,2001)
crack_adam7_inter(bt_ch_3,2001,2001)
crack_adam7_inter(bt_ch_3,20001,20001)
else:
crack_no_inter(bt_ch_1,20001)
crack_adam7_inter(bt_ch_22,2001,2001)
crack_adam7_inter(bt_ch_2,2001,2001)
crack_adam7_inter(bt_ch_1,10001,10001)