在C++Builder程序开发中,大量使用图像按钮,将程序需要隐藏的信息对应于这些按钮图像,能够起到信息隐藏的作用。为此我们提出了一种分散隐藏策略,建立了要隐藏的信息与多个按钮图像像素点颜色值之间的一一映射关系。分散隐藏的索引数据使用另外一个Bitmap图像来保存,增加了隐藏信息被破解的难度。

一、文字信息预处理

在C++Builder中,文字的数据类型为AnsiString,对任意一段文字text,使用下述语句转换成字节数组。

int len = text.Length();

int count=2*len+l;

char* array - new char [count];

BYTE* byt:es=new BYTE [count];

strcpy(array,text.c_str());

for (int i=O;i

{

bytes[i]=(BYTE)array[i];

)

在C++Builder中,BYTE定义为无符号字符型(Lmsigned char),取值区间为0~255,正好对应于颜色RGB值的分量取值范围。

为了加强保密强度,可以对字节数组bytes做进一步的变换。

二、TBitBtn图像分析

在C++Builder程序开发中,为了使软件界而更加友好,大量使用按钮、特别是图像按钮。图形按钮是一个TBitBtn类型的VCL控件,带有文字和图像,图像一般足32×16的Bitmap图像。

图像上每个像素点的颜色color用三个无符号整数r、g、b来表示,color=RGB(r,g,b),因此,可以在图像颜色与字节数组之问建立一一映射,这样,就可以将要隐藏的信息保存在图像中。

需要注意的是,TBitBtn控件上的图像是透明的图像,假设透明颜色为color0,则建立一一映射时应避开这些透明像素点。

TBitBtn的图像足一个32×16的Bitmap图像,实际上是两个16×16的Bitmap图像的合成。左边的图像用于正常显示;右边的图像用于在按钮处于不可使用情况下显示,在一般情况下不显示。因此,在字节数组与右边小图像之间建立一一映射关系可以使信息隐藏更具有隐蔽性。

三、分散隐藏策略

假设程序中使用了N个TBitBtn按钮,另有N个TBitBtn按钮备用,N=N+N。使用下面的方法在字节数组bytes与按钮图像之间建立一一映射关系。

定义三个整型数组A[count]、B[count]、C[count],其中:A[i]表示bytes[i]所对应的图像按钮的编号;B[i]表示bytes[i]所对应的按钮图像的像素点编号;C[i]表示像素点颜色分量编号,1为R分量,2为G分量,3为B分量。

分散隐藏算法如下:

(1)对i=0剑count-1进行循环;

(2)在O~N-I之间产生一个均匀分布的伪随机数a,令A[i]=a;C[i]=0;

(3)对j=0到255进行循环;

(4)取得第a个按钮图像的第j个像素点的颜色color,如果color=color0,则j++转下一个j循环;

(5)提取颜色分量r、g、b,

如果r=bYtes[i], B[i]=j,C[i]=1;

如果g=bYtes[i],B[i]=j,C[i]=2;

如果b=bYtes[i],B[i]=j,C[i]=3;

如果C[i]=0,则j++转下一个j循环;

(6)当j循环结束时C[i]=O,则转第(2)步;否则进入下一个i循环。

备用按钮的图像每个像素点的颜色依次用RGB(O,l,2)、RGB(3,4,5)等构成,目的是使字节数组中每个字节都能找到对应值,只要备用按钮个数足够多,这个假设一定成立。

为了增加隐蔽性,备用按钮的Visible属性应设置为不可见(false)。

四、索引信息的加密隐藏

为了在软件运行过程中恢复隐藏的信息,上述加密算法产生的数组A[i]、B[i]、C[i]需要保存在软件源代码中。

可以直接在程序源代码中定义三个整型数组,但是保密性不好。我们仍然使用Bitmap图像末保存这三个数组。

一个正整数可以用一个DWORD型变量来表示,而DWORD型变量可以对应于一个RGB颜色值,因此,N及数组A可以用N+1个颜色值来表示。而数组B和C的每个元素值小于256,故可以将每个B[i]和c[i]与一个颜色值相对应,将B[i]和C[i]分别对应于颜色值的R和G分量(B分量末使用)。于是,保存这三个数组以供需要2N+1个颜色值。

令M是满足M2>2N+1的最小整数,定义一个MxM的Bitmap图像,使用下而的算法将数组A[i]、B[i]、C[i]写入该图像。

(l)k=-l;

(2)对i=0到M-I,执行i循环;

(3)对j=0剑M-I,执行j循环;

(4)如果k=-l,则:

Pixels[i][j]=N

k++,执行下一个j循环;

(5)如k>0果且kN且k<2N,则

Pixels[i][j]=RGB(B[k-N],C[k-N],O)

(7)如果k>2N,则算法结束。

在上面的算法中,Pixels[i][j]=color表示将图像的第i行j列的像素点的颜色值设置为color。另一个函数RGB(r,g,b)表示R分量、G分量、B分量的值分别为r、g、b的颜色值。在C++Builder中祠5可以找剑相对应的函数Pixels和RGB。

小知识之ANSIChar

它是一种超长字符串类型。
这种字符串的内存动态分配,引用计数,并使用了更新前拷贝(copy­-on-write)技术,存储于堆空间,长度没有限制(可以存储多达20亿个字符!)。其字符类型也是ANSIChar 类型。