b1
= [b[i:i+
7
] for i in range(
0
, len(b),
7
)]
for i in range(len(b1)):
b2
= chr(int(b1[i],
2
))
str
= str+b2
return str
def insert(im,bin1):
size
= im.size
length
= len(bin1)
k
=
0
flag
=
0
for i in range(size
[0]
):
for j in range(size
[1]
):
pixel_b
=bin(im.getpixel((i,j))[
2
]).replace(
'0b'
,
''
)
if pixel_b
[-1:]
<bin1
[k]
:
im.putpixel((i,j),(im.getpixel((i,j))
[0]
,im.getpixel((i,j))
[1]
,im.getpixel((i,j))
[2]
+1))
if pixel_b
[-1:]
>bin1
[k]
:
im.putpixel((i,j),(im.getpixel((i,j))
[0]
,im.getpixel((i,j))
[1]
,im.getpixel((i,j))
[2]
-1))
k
=k+
1
if
k
==length:
flag
=
1
break
if
flag
==
1
:
break
print("字符串嵌入完成\n\n")
def extract(im,length):
size
= im.size
k
=
0
result
=
''
flag
=
0
for i in range(size
[0]
):
for j in range(size
[1]
):
pixel_b
=bin(im.getpixel((i,j))[
2
]).replace(
'0b'
,
''
)
result
=result+pixel_b[-
1
:]
k
=k+
1
if
k
==length:
flag
=
1
break
if
flag
==
1
:
break
print("提取完成,二进制字符串为:\n%s"%result)
str
= bin_convert_str(result)
print("转换完成,结果为:\n%s"%str)
def main():
test_str
=input(
"请输入字符串:\n"
)
result
= str_convert_bin(test_str)
print("待嵌入字符串转化为二进制为:\n%s"%result)
print("开始嵌入....")
im
= Image.open(
"2.bmp"
)
insert(im, result)
time.sleep(5)
print("开始提取字符串:")
extract(im, len(result))
if
__name__
==
'__main__'
:
main()
1.2 matlab 版本
后续更复杂的隐写还是需要用到matlab,于是乎还是转matlab吧。
matlab就不介绍了,我也是先学先用,代码写得粗糙,勉强贴上代码:
% By gengyanqing
% LSB隐藏(顺序隐藏)
% 可以隐藏数字、字母、英文字符 ex: hello,world.111
% jpg失真!用png/bmp
clear all
data=imread('1.png')
str=input('请输入要潜入的字符串:','s')
str_bin_mat=dec2bin(str)
% 二进制矩阵转字符串
l_str_bin_mat=size(str_bin_mat)
str_bin=''
for i=1:l_str_bin_mat(1)
for j=1:l_str_bin_mat(2)
str_bin=[str_bin,str_bin_mat(i,j)]
disp('待嵌入的字符串二进制形式为')
disp(str_bin)
% 检测是否能够完全嵌入
[l,w,h]=size(data)
if length(str_bin)>=l*w*h
error('字符长度超出!!!')
%嵌入程序
data1=data
disp('开始嵌入')
flag1=1
flag2=1
flag3=1
for i=1:l
if flag3==0
break
for j=1:w
if flag2==0
flag3=0
break
for k=1:h
if flag1>length(str_bin)
disp('over')
flag2=0
break
a=dec2bin(data1(i,j,k),8)
data1(i,j,k)=bin2dec([a(1:7),str_bin(flag1)])
flag1=flag1+1
%保存图片
imwrite(data1,'1-2.png')
disp('嵌入完成,保存为1-2.png')
%以下为提取程序
disp('开始提取...')
data2 = imread('1-2.png')
[l,w,h]=size(data2)
str_bin1=''
locationx=[]
locationy=[]
locationxy=[]
m=length(str_bin)
flag1=1
flag2=1
flag3=1
for i=1:l
if flag3==0
break
for j=1:w
if flag2==0
flag3=0
break
for k=1:h
if flag1>length(str_bin)
flag2=0
break
a=dec2bin(data2(i,j,k),8)
str_bin1=[str_bin1,a(8)]
flag1=flag1+1
disp('提取完成!')
disp('提取到的二进制字符串为:')
disp(str_bin1)
disp('开始转换...')
% 二进制转字符串
str2=''
for q=1:length(str_bin1)/l_str_bin_mat(2)
w=str_bin1((q-1)*l_str_bin_mat(2)+1:q*l_str_bin_mat(2))
a=bin2dec(w)
if a>9
str2=[str2,char(a)]
if a<9
str2=[str2,a]
disp('转换完成')
disp('最终结果为:')
disp(str2)
可以嵌字符,数字,字母,结果如下:
2. 随机LSB隐写
其实这个和顺序差不多,无非就是在遍历像素点的时候,将(i,j)改为随机的点,我们可以写个随机函数随机生成列表X和Y,当要嵌入(i,j)时我们就将其变为(X(i+j), Y(i+j)),为什么不是(X(i), Y(j))读者可以想想(这样不随机)。
这个我也画了一个流程图,但是好像有问题,时间紧急就暂且这样吧。
接下来看生成随机列表的函数 randomxy.m:
% 随机生成两个列表
% l为长,w为宽,len_str_bin为嵌入二进制长度,key为随机种子
function [x,y]=randxy(l,w,len_str_bin,key)
%设置随机种子,生成一串随机数
rand('seed',key)
disp('hhhhhhhhh')
x=randperm(l,len_str_bin)
y=randperm(w,len_str_bin)
%x = unique(x)
%y = unique(y)
然后看主要代码:
% By gengyanqing
% LSB隐藏(随机隐藏)
% 可以隐藏数字、字母、英文字符 ex: hello,world.111
% jpg失真!用png/bmp
clear all
data=imread('1.png')
str=input('请输入要潜入的字符串:','s')
str_bin_mat=dec2bin(str)
% 二进制矩阵转字符串
l_str_bin_mat=size(str_bin_mat)
str_bin=''
for i=1:l_str_bin_mat(1)
for j=1:l_str_bin_mat(2)
str_bin=[str_bin,str_bin_mat(i,j)]
disp('待嵌入的字符串二进制形式为')
disp(str_bin)
% 检测是否能够完全嵌入
[l,w,h]=size(data)
if length(str_bin)>=l*w*h
error('字符长度超出!!!')
%嵌入程序
data1=data
disp('开始嵌入')
flag1=1
flag2=1
flag3=1
% 调用randxy函数
[x,y]=randxy(l,w,length(str_bin),88)
for i=1:l
if flag3==0
break
for j=1:w
if flag2==0
flag3=0
break
for k=1:h
if flag1>length(str_bin)
disp('over')
flag2=0
break
a=dec2bin(data1(x(i+j),y(i+j),k),8)
data1(x(i+j),y(i+j),k)=bin2dec([a(1:7),str_bin(flag1)])
flag1=flag1+1
%保存图片
imwrite(data1,'1-2.png')
disp('嵌入完成,保存为1-2.png')
%以下为提取程序
%这里提供了x和y,提取二进制字符串位数的信息
disp('开始提取...')
data2 = imread('1-2.png')
[l,w,h]=size(data2)
str_bin1=''
locationx=[]
locationy=[]
locationxy=[]
m=length(str_bin)
flag1=1
flag2=1
flag3=1
for i=1:l
if flag3==0
break
for j=1:w
if flag2==0
flag3=0
break
for k=1:h
if flag1>length(str_bin)
flag2=0
break
a=dec2bin(data2(x(i+j),y(i+j),k),8)
locationx=[locationx,x(i+j)]
locationy=[locationy,y(i+j)]
locationxy=[locationxy
str_bin1=[str_bin1,a(8)]
flag1=flag1+1
disp('提取完成!')
disp('提取到的二进制字符串为:')
disp(str_bin1)
disp('开始转换...')
% 二进制转字符串
str2=''
for q=1:length(str_bin1)/l_str_bin_mat(2)
w=str_bin1((q-1)*l_str_bin_mat(2)+1:q*l_str_bin_mat(2))
a=bin2dec(w)
if a>9
str2=[str2,char(a)]
if a<9
str2=[str2,a]
disp('转换完成')
disp('最终结果为:')
disp(str2)
disp('随机位置分别为')
disp(locationxy)
plot(locationx,locationy)
下图为隐藏点的图(可以看出来确实是随机的)
