Initial commit

This commit is contained in:
kailai 2021-12-30 19:48:37 +08:00
parent 39c5f79e55
commit d843ca2c7f
135 changed files with 117078 additions and 2 deletions

31
DCT.py Normal file
View File

@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 11 17:10:43 2019
@author: Administrator
"""
import cv2
import numpy as np
img = cv2.imread('a.png',0)
img1 = img.astype('float')
def dct(m):
m = np.float32(m)/255.0
return cv2.dct(m)*255
#print(dct(img1).shape)
new_dct=dct(img1)
after_dct=[]
for i in range(len(new_dct)):
for j in range(len(new_dct[0])):
after_dct.append(int(new_dct[i][j]))
#print(new_dct)
#new_dct=new_dct.reshape(-1,1)
#print(len(after_dct))
#print(after_dct[:600])

60
F3.py Normal file
View File

@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 10 17:30:40 2019
@author: Administrator
"""
from Jsteg import Jsteg
class F3(Jsteg):
def __init__(self):
Jsteg.__init__(self)
def set_sequence_after_dct(self,sequence_after_dct):
self.sequence_after_dct=sequence_after_dct
sum_len=len(self.sequence_after_dct)
zero_len=len([i for i in self.sequence_after_dct if i==0])
one_len=len([i for i in self.sequence_after_dct if i in (-1,1)])
self.available_info_len=sum_len-zero_len-one_len # 不是特别可靠
print ("Load>> 大约可嵌入",sum_len-zero_len-int(one_len/2),'bits')
print ("Load>> 最少可嵌入",self.available_info_len,'bits\n')
def _write(self,index,data):
origin=self.sequence_after_dct[index]
if origin == 0:
return False
elif origin in (-1,1) and data==0:
self.sequence_after_dct[index]=0
return False
lower_bit=origin%2
if lower_bit==data:
pass
elif origin>0:
self.sequence_after_dct[index]=origin-1
elif origin<0:
self.sequence_after_dct[index]=origin+1
return True
def _read(self,index):
if self.sequence_after_dct[index] != 0:
return self.sequence_after_dct[index]%2
else:
return None
if __name__=="__main__":
f3=F3()
# 写
sequence_after_dct=[-1,0,1]*100+[i for i in range(-7,500)]
f3.set_sequence_after_dct(sequence_after_dct)
info1=[0,1,0,1,1,0,1,0]
f3.write(info1)
# 读
sequence_after_dct2=f3.get_sequence_after_dct()
f3.set_sequence_after_dct(sequence_after_dct2)
info2=f3.read()
print (info2)

67
F4.py Normal file
View File

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 11 16:10:51 2019
@author: Administrator
"""
from Jsteg import Jsteg
class F4(Jsteg):
def __init__(self):
Jsteg.__init__(self)
def set_sequence_after_dct(self,sequence_after_dct):
self.sequence_after_dct=sequence_after_dct
sum_len=len(self.sequence_after_dct)
zero_len=len([i for i in self.sequence_after_dct if i==0])
one_len=len([i for i in self.sequence_after_dct if i in (-1,1)])
self.available_info_len=sum_len-zero_len-one_len # 不是特别可靠
print ("Load>> 大约可嵌入",sum_len-zero_len-int(one_len/2),'bits')
print ("Load>> 最少可嵌入",self.available_info_len,'bits\n')
def _write(self,index,data):
origin=self.sequence_after_dct[index]
if origin == 0:
return False
elif origin == 1 and data==0:
self.sequence_after_dct[index]=0
return False
elif origin == -1 and data==1:
self.sequence_after_dct[index]=0
return False
lower_bit=origin%2
if origin >0:
if lower_bit!=data:
self.sequence_after_dct[index]=origin-1
else:
if lower_bit==data:
self.sequence_after_dct[index]=origin+1
return True
def _read(self,index):
if self.sequence_after_dct[index] >0:
return self.sequence_after_dct[index]%2
elif self.sequence_after_dct[index]<0:
return (self.sequence_after_dct[index]+1)%2
else:
return None
if __name__=="__main__":
f4=F4()
# 写
sequence_after_dct=[-1,0,1]*100+[i for i in range(-7,500)]
f4.set_sequence_after_dct(sequence_after_dct)
info1=[0,1,0,1,1,0,1,0]
f4.write(info1)
# 读
sequence_after_dct2=f4.get_sequence_after_dct()
f4.set_sequence_after_dct(sequence_after_dct2)
info2=f4.read()
print (info2)

128
Jsteg.py Normal file
View File

@ -0,0 +1,128 @@
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 10 15:26:43 2019
@author: Administrator
"""
import math
class Jsteg:
def __init__(self):
self.sequence_after_dct=None
def set_sequence_after_dct(self,sequence_after_dct):
self.sequence_after_dct=sequence_after_dct
self.available_info_len=len([i for i in self.sequence_after_dct if i not in (-1,1,0)]) # 不是绝对可靠的
print ("Load>> 可嵌入",self.available_info_len,'bits')
def get_sequence_after_dct(self):
return self.sequence_after_dct
def write(self,info):
"""先嵌入信息的长度,然后嵌入信息"""
info=self._set_info_len(info)
info_len=len(info)
info_index=0
im_index=0
while True:
if info_index>=info_len:
break
data=info[info_index]
if self._write(im_index,data):
info_index+=1
im_index+=1
def read(self):
"""先读出信息的长度,然后读出信息"""
_len,sequence_index=self._get_info_len()
info=[]
info_index=0
while True:
if info_index>=_len:
break
data=self._read(sequence_index)
if data!=None:
info.append(data)
info_index+=1
sequence_index+=1
return info
#===============================================================#
def _set_info_len(self,info):
l=int(math.log(self.available_info_len,2))+1
info_len=[0]*l
_len=len(info)
info_len[-len(bin(_len))+2:]=[int(i) for i in bin(_len)[2:]]
return info_len+info
def _get_info_len(self):
l=int(math.log(self.available_info_len,2))+1
len_list=[]
_l_index=0
_seq_index=0
while True:
if _l_index>=l:
break
_d=self._read(_seq_index)
if _d!=None:
len_list.append(str(_d))
_l_index+=1
_seq_index+=1
_len=''.join(len_list)
_len=int(_len,2)
return _len,_seq_index
# 注意经过DCT会有负值此处最低有效位的嵌入方式与空域LSB略有不同
def _write(self,index,data):
origin=self.sequence_after_dct[index]
if origin in (-1,1,0):
return False
lower_bit=origin%2
if lower_bit==data:
pass
elif origin>0:
if (lower_bit,data) == (0,1):
self.sequence_after_dct[index]=origin+1
elif (lower_bit,data) == (1,0):
self.sequence_after_dct[index]=origin-1
elif origin<0:
if (lower_bit,data) == (0,1):
self.sequence_after_dct[index]=origin-1
elif (lower_bit,data) == (1,0):
self.sequence_after_dct[index]=origin+1
return True
def _read(self,index):
if self.sequence_after_dct[index] not in (-1,1,0):
return self.sequence_after_dct[index]%2
else:
return None
'''
import cv2
import numpy as np
def dct(m):
m = np.float32(m)/255.0
return cv2.dct(m)*255
'''
if __name__=="__main__":
jsteg=Jsteg()
# 写
sequence_after_dct=[-1,0,1]*100+[i for i in range(-7,500)]
#print(sequence_after_dct)
jsteg.set_sequence_after_dct(sequence_after_dct)
info1=[0,1,0,1,1,0,1,0]
jsteg.write(info1)
sequence_after_dct2=jsteg.get_sequence_after_dct()
# 读
jsteg.set_sequence_after_dct(sequence_after_dct2)
info2=jsteg.read()
print (info2)

1
LSB/flag.txt Normal file
View File

@ -0,0 +1 @@
dajkhfahjkf

1
LSB/get_flag.txt Normal file
View File

@ -0,0 +1 @@
dajkhfahjkf

69
LSB/get_info.py Normal file
View File

@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
"""
Created on Sun May 19 12:43:26 2019
@author: Administrator
"""
from PIL import Image
def mod(x,y):
return x%y
def toasc(strr):
return int(strr, 2)
#le为所要提取的信息的长度str1为加密载体图片的路径str2为提取文件的保存路径
def func(le,str1,str2):
b=""
im = Image.open(str1)
lenth = le*8
width,height = im.size[0],im.size[1]
count = 0
for h in range(height):
for w in range(width):
#获得(w,h)点像素的值
pixel = im.getpixel((w, h))
#此处余3依次从R、G、B三个颜色通道获得最低位的隐藏信息
if count%3==0:
count+=1
b=b+str((mod(int(pixel[0]),2)))
if count ==lenth:
break
if count%3==1:
count+=1
b=b+str((mod(int(pixel[1]),2)))
if count ==lenth:
break
if count%3==2:
count+=1
b=b+str((mod(int(pixel[2]),2)))
if count ==lenth:
break
if count == lenth:
break
with open(str2,"w",encoding='utf-8') as f:
for i in range(0,len(b),8):
#以每8位为一组二进制转换为十进制
stra = toasc(b[i:i+8])
#将转换后的十进制数视为ascii码再转换为字符串写入到文件中
#print((stra))
f.write(chr(stra))
print("完成信息提取!")
def main():
#文件长度
le = 11
#含有隐藏信息的图片
new = "new.png"
#信息提取出后所存放的文件
get_info = "get_flag.txt"
func(le,new,get_info)
if __name__=='__main__':
main()

85
LSB/hide_info.py Normal file
View File

@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
"""
Created on Sun May 19 11:20:05 2019
@author: Administrator
"""
from PIL import Image
def plus(string):
#Python zfill() 方法返回指定长度的字符串原字符串右对齐前面填充0。
return string.zfill(8)
def get_key(strr):
#获取要隐藏的文件内容
with open(strr,"rb") as f:
s = f.read()
string=""
for i in range(len(s)):
#逐个字节将要隐藏的文件内容转换为二进制,并拼接起来
#1.先用ord()函数将s的内容逐个转换为ascii码
#2.使用bin()函数将十进制的ascii码转换为二进制
#3.由于bin()函数转换二进制后,二进制字符串的前面会有"0b"来表示这个字符串是二进制形式所以用replace()替换为空
#4.又由于ascii码转换二进制后是七位而正常情况下每个字符由8位二进制组成所以使用自定义函数plus将其填充为8位
string=string+""+plus(bin(s[i]).replace('0b',''))
#print(string)
return string
def mod(x,y):
return x%y
#str1为载体图片路径str2为隐写文件str3为加密图片保存的路径
def func(str1,str2,str3):
im = Image.open(str1)
#获取图片的宽和高
width,height= im.size[0],im.size[1]
print("width:"+str(width))
print("height:"+str(height))
count = 0
#获取需要隐藏的信息
key = get_key(str2)
keylen = len(key)
for h in range(height):
for w in range(width):
pixel = im.getpixel((w,h))
a=pixel[0]
b=pixel[1]
c=pixel[2]
if count == keylen:
break
#下面的操作是将信息隐藏进去
#分别将每个像素点的RGB值余2这样可以去掉最低位的值
#再从需要隐藏的信息中取出一位,转换为整型
#两值相加,就把信息隐藏起来了
a= a-mod(a,2)+int(key[count])
count+=1
if count == keylen:
im.putpixel((w,h),(a,b,c))
break
b =b-mod(b,2)+int(key[count])
count+=1
if count == keylen:
im.putpixel((w,h),(a,b,c))
break
c= c-mod(c,2)+int(key[count])
count+=1
if count == keylen:
im.putpixel((w,h),(a,b,c))
break
if count % 3 == 0:
im.putpixel((w,h),(a,b,c))
im.save(str3)
def main():
#原图
old = "old.png"
#处理后输出的图片路径
new = "new.png"
#需要隐藏的信息
enc = "flag.txt"
func(old,enc,new)
if __name__=='__main__':
main()

BIN
LSB/new.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
LSB/old.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

282
PDF/PDF格式.md Normal file
View File

@ -0,0 +1,282 @@
# PDF格式学习
## PDF简介
* PDF是Portable Document Format 的缩写可翻译为“便携文件格式”由Adobe System Incorporated 公司在1992年发明。
* PDF文件是一种编程形式的文档格式它所有显示的内容都是通过相应的操作符进行绘制的。
* PDF基本显示单元包括文字图片矢量图图片
* PDF扩展单元包括水印电子署名注释表单多媒体3D
* PDF动作单元书签超链接拥有动作的单元有很多个包括电子署名多媒体等等
## PDF的优点
* 一致性:
在所有可以打开PDF的机器上展示的效果是完全一致不会出现段落错乱、文字乱码这些排版问题。尤其是文档中本身可以嵌入字体避免了客户端没有对应字体而导致文字显示不一致的问题。所以在印刷行业绝大多数用的都是PDF格式。
* 不易修改:
用过PDF文件的人都会知道对已经保存之后的PDF文件想要进行重新排版基本上就不可能的这就保证了从资料源发往外界的资料不容易被篡改。
* 安全性:
PDF文档可以进行加密包括以下几种加密形式文档打开密码文档权限密码文档证书密码加密的方法包括RC4AES通过加密这种形式可以达到资料防扩散等目的。
* 不失真:
PDF文件中使用了矢量图在文件浏览时无论放大多少倍都不会导致使用矢量图绘制的文字图案的失真。
* 支持多种压缩方式:
为了减少PDF文件的sizePDF格式支持各种压缩方式 asciihexascii85lzwrunlengthccittjbig2jpeg(DCT)jpeg2000(jpx)
* 支持多种印刷标准:
支持PDF-APDF-X
## PDF格式
根据PDF官方指南理解PDF格式可以从四个方面下手——**Objects**(对象)、**File structure**(物理文件结构)、**Document structure**(逻辑文件结构)、**Content streams**(内容流)。
### 对象
### 物理文件结构
* 整体上分为文件头Header、对象集合Body、交叉引用表Xref table、文件尾Trailer四个部分结构如图。修改过的PDF结构会有部分变化。
* 未经修改
![未经修改](https://img-blog.csdnimg.cn/20190526170017719.png#pic_center)
* 经修改
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190526170402806.png#pic_center)
#### 文件头
* 文件头是PDF文件的第一行,格式如下:
```
%PDF-1.7
```
* 这是个固定格式表示这个PDF文件遵循的PDF规范版本解析PDF的时候尽量支持高版本的规范以保证支持大多数工具生成的PDF文件。1.7版本支持1.0-1.7之间的所有版本。
#### 对象集合
* 这是一个PDF文件最重要的部分文件中用到的所有对象,包括文本、图象、音乐、视频、字体、超连接、加密信息、文档结构信息等等,都在这里定义。格式如下:
```
2 0 obj
...
end obj
```
* 一个对象的定义包含4个部分前面的2是**对象序号**其用来唯一标记一个对象0是**生成号**按照PDF规范如果一个PDF文件被修改那这个数字是累加的它和对象序号一起标记是原始对象还是修改后的对象但是实际开发中很少有用这种方式修改PDF的都是重新编排对象号obj和endobj是对象的定义范围可以抽象的理解为这就是一个左括号和右括号省略号部分是PDF规定的任意合法对象。
* 可以通过R关键字来引用任何一个对象比如要引用上面的对象可以使用2 0 R需要主意的是R关键字不仅可以引用一个已经定义的对象还可以引用一个并**不存在的对象**,而且效果就和引用了一个空对象一样。