BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / security / #35130同步于 2012/9/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Security机器人发帖

F5 隐写算法

zlnbobo
2012/9/12镜像同步4 回复
求大牛知道F5 隐写算法的代码~~~
订阅后,新回复会通过你的通知中心匿名送达。
4 条回复
Xsetc机器人#1 · 2012/9/13
F5.cpp #include "StdAfx.h" #include "F5.h" #include <iostream> using namespace std; /********************************** F5算法《变化密度、嵌入率和嵌入效率之间的关系》表 k n change density embedding rate embedding efficiency 1 1 50.00% 100.00% 2 2 3 25.00% 66.67% 2.67 3 7 12.50% 42.86% 3.43 4 15 6.25% 26.67% 4.27 5 31 3.12% 16.13% 5.16 6 63 1.56% 9.52% 6.09 7 127 0.78% 5.51% 7.06 8 255 0.39% 3.14% 8.03 9 511 0.20% 1.76% 9.02 我们假设有有一半的 -1、1会在编码后消耗为0 根据JPEG系数柱图,系数1、-1占1/2,所以实际上 [embedding rate] = [embedding rate] * 3 / 4; **********************************/ #define PERCENTAGE 4/3 struct { int _n; int _k; double _rate; }Mode[9]= {{0, 0, 0.0000}, {1, 1, 0.6667*PERCENTAGE}, {3, 2, 0.4286*PERCENTAGE}, {7, 3, 0.2667*PERCENTAGE}, {15, 4, 0.1613*PERCENTAGE}, {31, 5, 0.0952*PERCENTAGE}, {63, 6, 0.0551*PERCENTAGE}, {127, 7, 0.0314*PERCENTAGE}, {511, 8, 0.0176*PERCENTAGE} }; CF5::CF5(void) { fAValue = -1; index = -1; n = -1; k = -1; r = -1; message = 0x0; msgRStart = 7; msgWStart = 7; tmpCode = 0x0; } CF5::~CF5(void) { } // 获得HASH函数f(a) // 返回f(a)的值fAValue,若出错返回-1 int CF5::makeHash(COEF** A, int lthN, int lthK) { //最多只能完成8位的矩阵编码 if(lthK > 8) return -1; int tmp; fAValue = 0; bool start = true; for( ; lthK>0; lthK--) { cout<<"f( "<<lthK<<" ) = "; tmp = 0; for(int i=1; i=lthN; i++) { tmp ^= ((*A[i-1])&0x1) * ((i>>(lthK-1)) & 0x1); if((i>>(lthK-1)) & 0x1) if(start) { cout<<"a"<<i<<"("<<(*A[i-1])<<"|"<<((*A[i-1])&0x1)<<")"; start = false; } else cout<<" + a"<<i<<"("<<(*A[i-1])<<"|"<<((*A[i-1])&0x1)<<")"; } cout<<" = "; cout<<tmp<<"\n"; hash[lthK-1] = tmp; start = true; fAValue ^= tmp<<(lthK-1); } cout<<"\n"; return fAValue; } int CF5::makeHash() { return makeHash(carrier, n, k); } // 嵌入k长信息,消耗bit // 修改A[]的对应位,返回修改值在数组的位置(1 ~ lthN),如没有修改返回0, 出错返回-1 int CF5::decrement(COEF** A, int lthK, BYTE msg) { int tmpL; BYTE tmpM; for(tmpL=lthK,tmpM=msg; tmpM!=0; tmpL--,tmpM>>=1); if(tmpL 0) //消息过长 return -1; if(fAValue == -1) //f(a)未计算出 return -1; index = msg ^ fAValue; if(index>0) //翻转最低位 *A[index-1] ^= 0x1; return index; } int CF5::decrement() { return decrement(carrier, k, message); } // 压缩测试 // 如果未生成0,返回0,如果生成0,则消除0位,返回1,如果无法消除0位,返回-1 int CF5::shrinkage(COEF **A, int lthN, COEF **Arest, COEFLENGTH* lArest) { int i; if(index == -1) //index未计算出 return -1; if(index == 0) //无改变 return 0; if((*A[index-1])==0) //生成0 { //消除0位 for(i=index-1; i<lthN-1; i++) A[i] = A[i+1]; for(; *lArest>0; (*lArest)--, (*Arest)++) if(**Arest != 0) { A[lthN-1] = *Arest; (*Arest)++; (*lArest)--; break; } if(0 > *lArest) //数据不够嵌入 return -1; return 1; } return 0; } int CF5::shrinkage(COEF **Arest, COEFLENGTH* lArest) { return shrinkage(carrier, n, Arest, lArest); } // 根据载体和密文容量确定n、k的值 // 若无合适值,返回-1,否则返回编码方式 int CF5::initPara(COEF** cof, COEFLENGTH lthCof, MSGLENGTH lthMsg) { //计算载体的有效容量 COEFLENGTH effective_coefficients_length = 0; for(COEFLENGTH i=0; i<lthCof; i++) if(0 != (*((*cof)+i))) effective_coefficients_length ++; double rate = (double)lthMsg / effective_coefficients_length; r = -1; for(int i=0; i<9; i++) if(rate Mode[i]._rate) { n = Mode[i]._n; k = Mode[i]._k; r = i; } return r; } // 嵌入算法 // 调用前需先调用initPara/setPara初始化模式 // 如嵌入成功,返回1;嵌入成功但仍有未嵌入的密文,返回0;嵌入失败返回-1 int CF5::embed(COEF** cof, COEFLENGTH* lthCof, BYTE** msg, MSGLENGTH* lthMsg) { CHK(r); msgRStart = 7; while((*lthCof)*Mode[r]._rate>(COEFLENGTH)k && (*lthMsg)>0) { CHK(getOneBuffer(cof, lthCof)); CHK(readMsg(msg, lthMsg)); do { CHK(makeHash()); CHK(decrement()); }while(1==shrinkage(cof, lthCof)); //密文已嵌入整数个字节,而剩下的载体不足以嵌入整数个字节或剩余的密文位剩下的长度 if(0==(*lthMsg)%8 && ((*lthCof)*Mode[r]._rate<8 || (*lthCof)*Mode[r]._rate<(*lthMsg))) break; } if((*lthMsg)>0) return 0; else return 1; } // 提取算法 // 调用前需先调用initPara/setPara初始化模式 // 如提取成功,返回1;提取失败返回-1 int CF5::distill(COEF** cof, COEFLENGTH* lthCof, BYTE** msg, MSGLENGTH lthMsg) { CHK(r); msgWStart = 7; MSGLENGTH lthWMsg = 0; while(lthWMsg<lthMsg) { CHK(getOneBuffer(cof, lthCof)); makeHash(); message = 0x0; for(int i=k-1; i>=0; i--) message ^= hash[i]<<i; writeMsg(msg, ((lthMsg-lthWMsg)<(MSGLENGTH)k)?(lthMsg-lthWMsg):k, <hWMsg); } return 0; } // 返回编码方式 int CF5::getMode(void) { return r; } // 从密文中读出本次矩阵编码的单位密文,长度为k // 成功返回 1,失败返回 -1 int CF5::readMsg(BYTE** msg, MSGLENGTH* lthMsg ) { if(*lthMsg=0) return -1; BYTE colander = 0x80; int i = 0; colander >>= 7-msgRStart; message = 0; while(i<k && (*lthMsg)>0) { message = (message<<1) ^ (((**msg)&colander)>>msgRStart); colander >>= 1; msgRStart --; i ++; (*lthMsg) --; if(colander == 0) { colander = 0x80; msgRStart = 7; (*msg) ++; } } if((*lthMsg) == 0) //剩余密文不够一次编码,用0补齐 message <= (k-i); return 1; } // 矩阵解码的单位密文写入密文流 // 成功返回 1,失败返回 -1 int CF5::writeMsg(BYTE** msg, int lthMsg, MSGLENGTH* lthTotleMsg) { int i = k-1; while(i>=0) { tmpCode |= ((message>>i)&0x1)<<msgWStart; msgWStart --; i --; if(msgWStart<0) { msgWStart = 7; *(*msg) ++ = tmpCode; tmpCode = 0x0; } } if(lthMsg<k) { msgWStart = 7; *(*msg) ++ = tmpCode; tmpCode = 0x0; } (*lthTotleMsg) += lthMsg; return 1; } // 设置编码模式 // 成功返回 1,失败返回 -1 int CF5::setPara(int _r) { if(r<0 || r>=9) return -1; r = _r; n = Mode[_r]._n; k = Mode[_r]._k; return 1; } // 返回编码模式 // 成功返回 1,失败返回 -1 int CF5::getPara(int* on, int* ok) { if(n==-1||k==-1) return -1; *on = n; *ok = k; return 1; } // 得到一单位长度的载体流 // 从系数数据中取出一个单位长度(n)的buffer用于矩阵编码 int CF5::getOneBuffer(COEF** cof, COEFLENGTH* lthCof) { for(int i=0; i<n; ) { if(0 != **cof) carrier[i++] = *cof; (*cof) ++; (*lthCof) --; if(*lthCof 0) { *cof = NULL; return -1; } } return 1; }
Xsetc机器人#2 · 2012/9/13
F5.h #pragma once #ifndef BYTE typedef unsigned char BYTE; #endif #define CHK(n) if(-1==n) return -1; typedef int COEF; typedef unsigned long COEFLENGTH; typedef unsigned long MSGLENGTH; class CF5 { public: CF5(void); ~CF5(void); // 嵌入 int embed(COEF** cof, COEFLENGTH* lthCof, BYTE** msg, MSGLENGTH* lthMsg); // 提取 int distill(COEF** cof, COEFLENGTH* lthCof, BYTE** msg, MSGLENGTH lthMsg); // 返回编码方式 int getMode(void); // 根据载体和密文容量确定n、k的值 int initPara(COEF** cof, COEFLENGTH lthCof, MSGLENGTH lthMsg); // 设置编码模式 int setPara(int _r); // 返回编码模式 int getPara(int* oN, int* oK); //private: // 获得HASH函数f(a) int makeHash(COEF** A, int lthN, int lthK); int makeHash(); // 嵌入k长信息,消耗bit int decrement(COEF** A, int lthK, BYTE msg); int decrement(); // 压缩测试 int shrinkage(COEF** A, int lthN, COEF **Arest, COEFLENGTH* lArest); int shrinkage(COEF **Arest, COEFLENGTH* lArest); // 从密文中读出本次矩阵编码的单位密文 int readMsg(BYTE** msg, MSGLENGTH* lthMsg); // 矩阵解码的单位密文写入密文流 int writeMsg(BYTE** msg, int lthMsg, MSGLENGTH* lthTotleMsg); // 得到一单位长度的载体流 int getOneBuffer(COEF** cof, COEFLENGTH* lthCof); //private: int fAValue; int index; int n; /*载体长度*/ int k; /*密文长度*/ int r; /*选择编码方式*/ COEF* carrier[127]; /*一次矩阵编码的单位载体*/ BYTE message; /*矩阵编码的单位密文*/ BYTE hash[8]; int msgRStart, /*密文读写开始位置*/ msgWStart; /*读出或写入的单位密文不一定是BYTE的倍数,用此记录密文开始的位置*/ BYTE tmpCode; /*存放不足写满1 byte的编码*/ };
Xsetc机器人#3 · 2012/9/13
Hash.cpp // Hash.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include "F5.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { /*0, 1, 2, 3, 4, 5, 6, 7, 8, 9*/ int a[] = {3, 4,-5,-1, 2, 2, 1, 0,-2, 0, 0, 0, 3, 2, 1,-2,-5, 3, 0, 1, 2 }; COEFLENGTH lengthC = 21; COEFLENGTH lengthA = lengthC; MSGLENGTH lengthM = 16; int* lpA = a; //BYTE msg = 0x6; //BYTE msg1[] = {0xf3,0xf2,0x51}; //BYTE msg2[] = {0xff,0x00,0xff}; BYTE msg3[] = {0xa3, 0xbe}; MSGLENGTH lengthM4 = 16; BYTE* Msg4 = (BYTE*)malloc(sizeof(BYTE)*lengthM4); BYTE* lpMsg4 = Msg4; //BYTE* lpMsg1 = msg1; //BYTE* lpMsg2 = msg2; BYTE* lpMsg3 = msg3; unsigned long lthMsgsg1 = 24, lthMsgsg2 = 0; CF5 f; //f.setPara(lengthA, lengthX); //f.getOneBuffer(&lpA, &length); //while(lthMsgsg1>0) //{ // f.readMsg(&lpMsg1, <hMsgsg1); // f.writeMsg(&lpMsg2, <hMsgsg2); //} //COEFLENGTH lRest = length-lengthA; //lpA += lengthA; //f.makeHash(a, lengthA, lengthX); //f.decrement(a, lengthX, msg); //f.shrinkage(a, lengthA, &lpA, &lRest); f.initPara(&lpA, lengthC, lengthM); f.embed(&lpA, &lengthC, &lpMsg3, &lengthM); lpA = a; f.distill(&lpA, &lengthA, &lpMsg4, lengthM4); return 0; }
zlnbobo机器人#4 · 2012/9/17
【 在 Xsetc 的大作中提到: 】 : F5.cpp : [code=c] : #include "StdAfx.h" : ................... 谢谢啦~~~