Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sys/stat.h>
- #include <cmath>
- #include <fstream>
- using namespace std;
- bool DEBUG = false;
- bool DEMONSTRATE = false;
- bool FILL_BACKGROUND = false;
- string intToBin(int byte){
- string result = "";
- while (byte > 0){
- result = byte%2?"1"+result:"0"+result;
- byte = byte / 2;
- }
- for(int i = result.size(); i < 8; i++){
- result = "0"+result;
- }
- return result;
- }
- int binToInt(string code){
- int result = 0;
- for(int i = 0; i < code.size(); i++){
- if(code[i] == '1'){
- result+= pow(2,code.size()-1-i);
- }
- }
- return result;
- }
- int** getHelpMatrix(){
- int N = 4;
- int M = 15;
- int** H = new int*[N];
- int conductor;
- int rate;
- bool discharge;
- for(int i = 0; i < N; i++){
- H[i] = new int[M];
- discharge = false;
- rate = pow(2,(N-i)-1);
- conductor=1;
- for(int j = 0; j < M; j++){
- if(conductor == rate) discharge = true;
- if(conductor == 0 ) discharge = false;
- if(discharge){
- H[i][j] = 1;
- conductor--;
- }else{
- H[i][j] = 0;
- conductor++;
- }
- }
- }
- return H;
- }
- string matrixMulVectorMod2(int** matrix, int N_matrx, int M_matrx, int *vector){
- int* result = new int[N_matrx];
- string resultBin = "";
- for(int j = 0; j < N_matrx; j++)
- result[j] = 0;
- for(int i = 0; i < N_matrx; i++){
- for(int j = 0; j < M_matrx; j++)
- result[i] = (result[i] + (matrix[i][j] * vector[j])%2)%2;
- }
- for(int j = 0; j < N_matrx; j++)
- resultBin += to_string(result[j]);
- return resultBin;
- }
- char* LSB_R(char* image, int N, string message, int step){
- if (message.size()*step > N) {
- cout<<"Message too big"<<endl;
- return image;
- }
- if(FILL_BACKGROUND){
- for(int i = 54; i < N; i++){
- image[i] = 255;
- }
- }
- int index = 54;
- string binary;
- for(int i = 0; i < message.size(); i++){
- binary = intToBin((int)message[i]);
- for(int j = 0; j < binary.size(); j++){
- image[index+(j*step)] = (char)((int)image[index+(j*step)] & 254);
- image[index+(j*step)] = (char)((int)image[index+(j*step)] | (binary[j]-48));
- if(DEMONSTRATE)
- image[index+(j*step)] = 0;
- }
- index+=8*step;
- }
- return image;
- }
- char* LSB_M_Pluse(char* image, int N, string message, int step){
- if (message.size()*step > N) {
- cout<<"Message too big"<<endl;
- return image;
- }
- if(FILL_BACKGROUND){
- for(int i = 54; i < N; i++){
- image[i] = 255;
- }
- }
- int index = 54;
- string binary;
- for(int i = 0; i < message.size(); i++){
- binary = intToBin((int)message[i]);
- for(int j = 0; j < binary.size(); j++){
- if (((int)image[index+(j*step)]&1) != (int)binary[j]-48){
- if((int)image[index+(j*step)] != 255){
- image[index+(j*step)] = (char)((int)image[index+(j*step)] + 1);
- }else{
- image[index+(j*step)] = (char)((int)image[index+(j*step)] & 254);
- image[index+(j*step)] = (char)((int)image[index+(j*step)] | (binary[j]-48));
- }
- if(DEMONSTRATE)
- image[index+(j*step)] = 0;
- }
- }
- index+=8*step;
- }
- return image;
- }
- int* initVector(int size){
- int* vector = new int[size];
- for(int i = 0; i < size; i++)
- vector[i] = 0;
- return vector;
- }
- char* Hamming15_11(char* image, int N, string message){
- int** helpMatrx = getHelpMatrix();
- int* c = initVector( 15);
- string Hc;
- int index = 54;
- if ((message.size()*30) > N){ //30 is (((size*8)/4)*15)
- cout<<"Message too big for this image"<<endl;
- return image;
- }
- string charBin;
- string w;
- int byte;
- int s;
- for(int i = 0; i < message.size(); i++){
- byte = (int)message[i];
- charBin = intToBin(byte);
- if(DEBUG)
- cout <<"msg[i] = "<<message[i]<<" byte = "<<byte<< " charBin = "<<charBin<<" ";
- for(int o = 0; o < 2; o++){
- w = charBin.substr(4*o, 4*(o+1));
- if(DEBUG)
- cout << "HalfcharBin"<<o+1<<" = "<<w<<" ";
- for(int j = 0; j < 15; j++)
- c[j] = image[index+j]&1;
- Hc = matrixMulVectorMod2(helpMatrx, 4, 15, c);
- s = binToInt(Hc) ^ binToInt(w);
- if( s != 0)
- c[s-1] = 1 - c[s-1];
- for(int j = 0; j < 15; j++){
- image[index+j] = (char)((int)image[index+j] & 254);
- image[index+j] = (char)((int)image[index+j] | c[j]);
- }
- if(DEMONSTRATE)
- if( s != 0)
- image[index+(s-1)] = 0;
- index +=15;
- }
- if(DEBUG)
- cout<<endl;
- }
- if(FILL_BACKGROUND){
- int step = 0;
- for(int i = 54; i < N; i++){
- if(image[i] != 0)
- image[i] = 255;
- /*if(step == 14){
- image[i] = 0;
- step = -1;
- }
- step++;*/
- }
- }
- return image;
- }
- string Hamming15_11_Decode(char *image, int n){
- int* c = initVector(15);
- int** helpMatrx = getHelpMatrix();
- string byte = "";
- int index = 54;
- int sizeMessage = 0;
- string result;
- int byteInt = 0;
- for(; index < 3000;){
- for(int o = 0; o < 2; o++){
- for(int j = 0; j < 15; j++)
- c[j] = image[index+j]&1;
- if( o == 0){
- byteInt += (binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c))*16);
- }else{
- byteInt += binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c));
- }
- index += 15;
- }
- if(byteInt == 1){
- sizeMessage = stoi(result);
- break;
- }
- result+=(char)byteInt;
- byteInt = 0;
- }
- byteInt = 0;
- result = "";
- for(int i = 0; i < sizeMessage; i++){
- for(int o = 0; o < 2; o++){
- for(int j = 0; j < 15; j++)
- c[j] = image[index+j]&1;
- if( o == 0){
- byteInt += (binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c))*16);
- }else{
- byteInt += binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c));
- }
- index += 15;
- }
- result+=(char)byteInt;
- byteInt = 0;
- }
- return result;
- }
- string LSBDecode(char *image, int n, int step) {
- string byte = "";
- int index = 54;
- int sizeMessage = 0;
- string result;
- for(int i = 0; index < n; i++){
- for(int j = 0; j < 8; j++){
- byte += to_string((int)image[index+(j*step)]&1);
- }
- index+=8*step;
- if(binToInt(byte) == 1){
- sizeMessage = stoi(result);
- break;
- }
- result+=(char)binToInt(byte);
- byte = "";
- }
- result = "";
- for(int i = 0; i < sizeMessage; i++){
- for(int j = 0; j < 8; j++){
- byte += to_string((int)image[index+(j*step)]&1);
- }
- index+=8*step;
- result+=(char)binToInt(byte);
- byte = "";
- }
- return result;
- }
- int getCount(char* image, int N){
- int count = 0;
- for(int i = 54; i < N; i++){
- if(image[i] == 0)
- count++;
- }
- return count;
- }
- string pathBuilder(string method, string nameBmp, int step, bool demo, bool fill){
- string outPath = "../";
- outPath +=method+"/"+nameBmp+"_"+method;
- if(step > 0){
- outPath+="("+ to_string(step)+"step)";
- }
- if(demo)
- outPath += "_demo";
- if(fill)
- outPath += "_fill";
- outPath +=".bmp";
- return outPath;
- }
- string readFromFile(string fileName){
- string result = "";
- string str;
- ifstream fin;
- fin.open(fileName);
- if(!fin.is_open()){
- cout<<"Error read from file"<<endl;
- return "message";
- }else{
- while (!fin.eof()){
- getline(fin, str);
- result += str;
- if(!fin.eof())
- result+="\n";
- }
- }
- return result;
- }
- int main() {
- char *image;
- int N;
- struct stat st{};
- FILE *fp, *fp_out;
- ///---SETUP------///
- DEBUG = false;
- FILL_BACKGROUND = false; ///true false
- DEMONSTRATE = true;
- string nameBmp = "PU24-11";
- int choice = 1;
- int step = 61;
- ///--------------///
- string sourcePath = "../bmp/";
- string sourceStr = sourcePath+nameBmp+".bmp";
- char *source = new char[sourceStr.length() + 1];
- strcpy(source, sourceStr.c_str());
- string outPath;
- fp = fopen (source, "rb+");
- fstat(fileno(fp), &st);
- N = st.st_size;
- image = new char [N];
- fread(image, 1, N, fp);
- ///*Работа с картинкой*/
- string message = readFromFile("../text.txt");
- message = to_string(message.size())+((char)1)+message;
- string decode;
- if(DEMONSTRATE){
- for(int i = 54; i < N; i++){
- if(image[i] == 0)
- image[i] = 1;
- }
- }
- switch (choice) {
- case 1:
- image = LSB_R(image, N, message, step);
- if(!DEMONSTRATE){
- decode = LSBDecode(image, N,step);
- cout<<decode<<endl;
- }
- outPath = pathBuilder("LSB-R", nameBmp, step, DEMONSTRATE, FILL_BACKGROUND);
- break;
- case 2:
- image = LSB_M_Pluse(image, N, message, step);
- if(!DEMONSTRATE){
- decode = LSBDecode(image, N,step);
- cout<<decode<<endl;
- }
- outPath = pathBuilder("LSB-M-Pluse", nameBmp, step, DEMONSTRATE, FILL_BACKGROUND);
- break;
- case 3:
- Hamming15_11(image, N, message);
- if(!DEMONSTRATE)
- cout<< Hamming15_11_Decode(image, N)<<endl;
- outPath = pathBuilder("Hamming", nameBmp, 0, DEMONSTRATE, FILL_BACKGROUND);
- break;
- default:
- break;
- }
- cout<<"///---Stat-------"<<endl;
- cout<<"Size file = "<< N-54 <<endl;
- cout<<"Size msg in bit's = "<< message.size()*8 <<endl;
- if(choice == 1 || choice == 2){
- cout<<endl<<"///---";
- choice==1?cout<<"LSB_R":cout<<"LSB_M_Pluse";
- cout<<"__Info--- "<<endl;
- cout<<"a*Rate(max) a = "<< (1/(double)step) <<endl;
- cout<<"Size msg*step / N = "<< (message.size()*8*step/(double)(N-54)) <<endl;
- }else if(choice == 3){
- cout<<endl<<"///---Hamming__Info--- "<<endl;
- cout<<"Rate = "<< (4/(double)15) <<endl;
- }
- if(DEMONSTRATE){
- int count = getCount(image, N);
- cout<<"Count bit's with msg = "<< count << endl;
- cout<<"Persent msg in image = "<< count / (double)(N-54) << endl;
- }
- char *out = new char[outPath.length() + 1];
- strcpy(out, outPath.c_str());
- fp_out = fopen(out, "wb+");
- ///*Запись в файл*/
- fwrite(image, 1, N, fp_out);
- fclose(fp);
- fclose(fp_out);
- delete [] source;
- delete [] out;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement