Aaaaa988

55

Oct 8th, 2021
613
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <sys/stat.h>
  3. #include <cmath>
  4. #include <fstream>
  5.  
  6. using namespace std;
  7.  
  8. bool DEBUG = false;
  9. bool DEMONSTRATE = false;
  10. bool FILL_BACKGROUND = false;
  11.  
  12. string intToBin(int byte){
  13.     string result = "";
  14.     while (byte > 0){
  15.         result = byte%2?"1"+result:"0"+result;
  16.         byte = byte / 2;
  17.     }
  18.     for(int i = result.size(); i < 8; i++){
  19.         result = "0"+result;
  20.     }
  21.     return result;
  22. }
  23.  
  24. int binToInt(string code){
  25.     int result = 0;
  26.     for(int i = 0; i < code.size(); i++){
  27.         if(code[i] == '1'){
  28.             result+= pow(2,code.size()-1-i);
  29.         }
  30.     }
  31.     return result;
  32. }
  33.  
  34. int** getHelpMatrix(){
  35.     int N = 4;
  36.     int M = 15;
  37.     int** H = new int*[N];
  38.     int conductor;
  39.     int rate;
  40.     bool discharge;
  41.  
  42.     for(int i = 0; i < N; i++){
  43.         H[i] = new int[M];
  44.         discharge = false;
  45.         rate = pow(2,(N-i)-1);
  46.         conductor=1;
  47.         for(int j = 0; j < M; j++){
  48.             if(conductor == rate) discharge = true;
  49.             if(conductor == 0   ) discharge = false;
  50.             if(discharge){
  51.                 H[i][j] = 1;
  52.                 conductor--;
  53.             }else{
  54.                 H[i][j] = 0;
  55.                 conductor++;
  56.             }
  57.         }
  58.     }
  59.  
  60.     return H;
  61. }
  62.  
  63. string matrixMulVectorMod2(int** matrix, int N_matrx, int M_matrx, int *vector){
  64.     int* result = new int[N_matrx];
  65.     string resultBin = "";
  66.  
  67.     for(int j = 0; j < N_matrx; j++)
  68.         result[j] = 0;
  69.  
  70.     for(int i = 0; i < N_matrx; i++){
  71.         for(int j = 0; j < M_matrx; j++)
  72.             result[i] = (result[i] + (matrix[i][j] * vector[j])%2)%2;
  73.     }
  74.  
  75.     for(int j = 0; j < N_matrx; j++)
  76.         resultBin += to_string(result[j]);
  77.  
  78.  
  79.     return resultBin;
  80. }
  81.  
  82. char* LSB_R(char* image, int N, string message, int step){
  83.     if (message.size()*step > N) {
  84.         cout<<"Message too big"<<endl;
  85.         return image;
  86.     }
  87.  
  88.     if(FILL_BACKGROUND){
  89.         for(int i = 54; i < N; i++){
  90.             image[i] = 255;
  91.         }
  92.     }
  93.  
  94.     int index = 54;
  95.     string binary;
  96.     for(int i = 0; i < message.size(); i++){
  97.         binary = intToBin((int)message[i]);
  98.         for(int j = 0; j < binary.size(); j++){
  99.             image[index+(j*step)] = (char)((int)image[index+(j*step)] & 254);
  100.             image[index+(j*step)] = (char)((int)image[index+(j*step)] | (binary[j]-48));
  101.             if(DEMONSTRATE)
  102.                 image[index+(j*step)] = 0;
  103.         }
  104.         index+=8*step;
  105.  
  106.     }
  107.     return image;
  108. }
  109.  
  110. char* LSB_M_Pluse(char* image, int N, string message, int step){
  111.     if (message.size()*step > N) {
  112.         cout<<"Message too big"<<endl;
  113.         return image;
  114.     }
  115.  
  116.     if(FILL_BACKGROUND){
  117.         for(int i = 54; i < N; i++){
  118.             image[i] = 255;
  119.         }
  120.     }
  121.  
  122.     int index = 54;
  123.     string binary;
  124.     for(int i = 0; i < message.size(); i++){
  125.         binary = intToBin((int)message[i]);
  126.         for(int j = 0; j < binary.size(); j++){
  127.             if (((int)image[index+(j*step)]&1) != (int)binary[j]-48){
  128.                 if((int)image[index+(j*step)] != 255){
  129.                     image[index+(j*step)] = (char)((int)image[index+(j*step)] + 1);
  130.                 }else{
  131.                     image[index+(j*step)] = (char)((int)image[index+(j*step)] & 254);
  132.                     image[index+(j*step)] = (char)((int)image[index+(j*step)] | (binary[j]-48));
  133.                 }
  134.                 if(DEMONSTRATE)
  135.                     image[index+(j*step)] = 0;
  136.             }
  137.         }
  138.         index+=8*step;
  139.     }
  140.     return image;
  141. }
  142.  
  143. int* initVector(int size){
  144.     int* vector = new int[size];
  145.     for(int i = 0; i < size; i++)
  146.         vector[i] = 0;
  147.     return vector;
  148. }
  149.  
  150. char* Hamming15_11(char* image, int N, string message){
  151.     int** helpMatrx = getHelpMatrix();
  152.     int* c = initVector( 15);
  153.     string Hc;
  154.     int index = 54;
  155.     if ((message.size()*30) > N){ //30 is (((size*8)/4)*15)
  156.         cout<<"Message too big for this image"<<endl;
  157.         return image;
  158.     }
  159.  
  160.     string charBin;
  161.     string w;
  162.     int byte;
  163.     int s;
  164.     for(int i = 0; i < message.size(); i++){
  165.  
  166.         byte = (int)message[i];
  167.         charBin = intToBin(byte);
  168.  
  169.         if(DEBUG)
  170.             cout <<"msg[i] = "<<message[i]<<" byte = "<<byte<< " charBin = "<<charBin<<" ";
  171.         for(int o = 0; o < 2; o++){
  172.             w = charBin.substr(4*o, 4*(o+1));
  173.  
  174.             if(DEBUG)
  175.                 cout << "HalfcharBin"<<o+1<<" = "<<w<<" ";
  176.  
  177.             for(int j = 0; j < 15; j++)
  178.                 c[j] = image[index+j]&1;
  179.  
  180.             Hc = matrixMulVectorMod2(helpMatrx, 4, 15, c);
  181.             s = binToInt(Hc) ^ binToInt(w);
  182.             if( s != 0)
  183.                 c[s-1] = 1 - c[s-1];
  184.  
  185.             for(int j = 0; j < 15; j++){
  186.                 image[index+j] = (char)((int)image[index+j] & 254);
  187.                 image[index+j] = (char)((int)image[index+j] | c[j]);
  188.             }
  189.  
  190.             if(DEMONSTRATE)
  191.                 if( s != 0)
  192.                     image[index+(s-1)] = 0;
  193.  
  194.             index +=15;
  195.         }
  196.         if(DEBUG)
  197.             cout<<endl;
  198.     }
  199.  
  200.     if(FILL_BACKGROUND){
  201.         int step = 0;
  202.         for(int i = 54; i < N; i++){
  203.             if(image[i] != 0)
  204.                 image[i] = 255;
  205.                 /*if(step == 14){
  206.                     image[i] = 0;
  207.                     step = -1;
  208.                 }
  209.                 step++;*/
  210.         }
  211.     }
  212.  
  213.  
  214.     return image;
  215. }
  216.  
  217. string Hamming15_11_Decode(char *image, int n){
  218.     int* c = initVector(15);
  219.     int** helpMatrx = getHelpMatrix();
  220.     string byte = "";
  221.     int index = 54;
  222.     int sizeMessage = 0;
  223.     string result;
  224.     int byteInt = 0;
  225.  
  226.     for(; index < 3000;){
  227.  
  228.         for(int o = 0; o < 2; o++){
  229.             for(int j = 0; j < 15; j++)
  230.                 c[j] = image[index+j]&1;
  231.  
  232.             if( o == 0){
  233.                 byteInt += (binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c))*16);
  234.             }else{
  235.                 byteInt += binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c));
  236.             }
  237.  
  238.             index += 15;
  239.         }
  240.  
  241.         if(byteInt == 1){
  242.             sizeMessage = stoi(result);
  243.             break;
  244.         }
  245.         result+=(char)byteInt;
  246.         byteInt = 0;
  247.     }
  248.     byteInt = 0;
  249.     result = "";
  250.  
  251.     for(int i = 0; i < sizeMessage; i++){
  252.  
  253.         for(int o = 0; o < 2; o++){
  254.             for(int j = 0; j < 15; j++)
  255.                 c[j] = image[index+j]&1;
  256.  
  257.             if( o == 0){
  258.                 byteInt += (binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c))*16);
  259.             }else{
  260.                 byteInt += binToInt(matrixMulVectorMod2(helpMatrx, 4, 15, c));
  261.             }
  262.  
  263.             index += 15;
  264.         }
  265.  
  266.         result+=(char)byteInt;
  267.         byteInt = 0;
  268.     }
  269.  
  270.     return result;
  271. }
  272.  
  273.  
  274.  
  275. string LSBDecode(char *image, int n, int step) {
  276.     string byte = "";
  277.     int index = 54;
  278.     int sizeMessage = 0;
  279.     string result;
  280.     for(int i = 0; index < n; i++){
  281.         for(int j = 0; j < 8; j++){
  282.             byte += to_string((int)image[index+(j*step)]&1);
  283.         }
  284.         index+=8*step;
  285.         if(binToInt(byte) == 1){
  286.             sizeMessage = stoi(result);
  287.             break;
  288.         }
  289.         result+=(char)binToInt(byte);
  290.         byte = "";
  291.     }
  292.     result = "";
  293.     for(int i = 0; i < sizeMessage; i++){
  294.         for(int j = 0; j < 8; j++){
  295.             byte += to_string((int)image[index+(j*step)]&1);
  296.         }
  297.         index+=8*step;
  298.  
  299.         result+=(char)binToInt(byte);
  300.         byte = "";
  301.     }
  302.  
  303.     return result;
  304. }
  305.  
  306. int getCount(char* image, int N){
  307.     int count = 0;
  308.     for(int i = 54; i < N; i++){
  309.         if(image[i] == 0)
  310.             count++;
  311.     }
  312.     return count;
  313. }
  314.  
  315. string pathBuilder(string method, string nameBmp, int step, bool demo, bool fill){
  316.     string outPath = "../";
  317.     outPath +=method+"/"+nameBmp+"_"+method;
  318.     if(step > 0){
  319.         outPath+="("+ to_string(step)+"step)";
  320.     }
  321.     if(demo)
  322.         outPath += "_demo";
  323.     if(fill)
  324.         outPath += "_fill";
  325.     outPath +=".bmp";
  326.  
  327.     return outPath;
  328. }
  329.  
  330. string readFromFile(string fileName){
  331.     string result = "";
  332.     string str;
  333.     ifstream fin;
  334.     fin.open(fileName);
  335.     if(!fin.is_open()){
  336.         cout<<"Error read from file"<<endl;
  337.         return "message";
  338.     }else{
  339.         while (!fin.eof()){
  340.             getline(fin, str);
  341.             result += str;
  342.             if(!fin.eof())
  343.                 result+="\n";
  344.         }
  345.     }
  346.     return result;
  347. }
  348.  
  349. int main() {
  350.     char *image;
  351.     int N;
  352.     struct stat st{};
  353.     FILE *fp, *fp_out;
  354.  
  355.  
  356.     ///---SETUP------///
  357.     DEBUG = false;
  358.  
  359.     FILL_BACKGROUND = false; ///true false
  360.     DEMONSTRATE = true;
  361.  
  362.     string nameBmp = "PU24-11";
  363.     int choice = 1;
  364.     int step = 61;
  365.     ///--------------///
  366.  
  367.     string sourcePath = "../bmp/";
  368.     string sourceStr = sourcePath+nameBmp+".bmp";
  369.     char *source = new char[sourceStr.length() + 1];
  370.     strcpy(source, sourceStr.c_str());
  371.  
  372.     string outPath;
  373.  
  374.     fp = fopen (source, "rb+");
  375.  
  376.     fstat(fileno(fp), &st);
  377.     N = st.st_size;
  378.     image = new char [N];
  379.     fread(image, 1, N, fp);
  380.  
  381.     ///*Работа с картинкой*/
  382.     string message = readFromFile("../text.txt");
  383.     message = to_string(message.size())+((char)1)+message;
  384.     string decode;
  385.  
  386.     if(DEMONSTRATE){
  387.         for(int i = 54; i < N; i++){
  388.             if(image[i] == 0)
  389.                 image[i] = 1;
  390.         }
  391.     }
  392.  
  393.     switch (choice) {
  394.         case 1:
  395.             image = LSB_R(image, N, message, step);
  396.             if(!DEMONSTRATE){
  397.                 decode = LSBDecode(image, N,step);
  398.                 cout<<decode<<endl;
  399.             }
  400.             outPath = pathBuilder("LSB-R", nameBmp, step, DEMONSTRATE, FILL_BACKGROUND);
  401.  
  402.             break;
  403.         case 2:
  404.             image = LSB_M_Pluse(image, N, message, step);
  405.             if(!DEMONSTRATE){
  406.                 decode = LSBDecode(image, N,step);
  407.                 cout<<decode<<endl;
  408.             }
  409.             outPath = pathBuilder("LSB-M-Pluse", nameBmp, step, DEMONSTRATE, FILL_BACKGROUND);
  410.  
  411.             break;
  412.         case 3:
  413.             Hamming15_11(image, N, message);
  414.             if(!DEMONSTRATE)
  415.                 cout<< Hamming15_11_Decode(image, N)<<endl;
  416.             outPath = pathBuilder("Hamming", nameBmp, 0, DEMONSTRATE, FILL_BACKGROUND);
  417.             break;
  418.         default:
  419.             break;
  420.     }
  421.  
  422.     cout<<"///---Stat-------"<<endl;
  423.  
  424.     cout<<"Size file = "<< N-54 <<endl;
  425.     cout<<"Size msg in bit's  = "<< message.size()*8 <<endl;
  426.     if(choice == 1 || choice == 2){
  427.         cout<<endl<<"///---";
  428.         choice==1?cout<<"LSB_R":cout<<"LSB_M_Pluse";
  429.         cout<<"__Info--- "<<endl;
  430.         cout<<"a*Rate(max)        a = "<< (1/(double)step) <<endl;
  431.         cout<<"Size msg*step / N    = "<< (message.size()*8*step/(double)(N-54)) <<endl;
  432.     }else if(choice == 3){
  433.         cout<<endl<<"///---Hamming__Info--- "<<endl;
  434.         cout<<"Rate = "<< (4/(double)15) <<endl;
  435.     }
  436.     if(DEMONSTRATE){
  437.         int count = getCount(image, N);
  438.         cout<<"Count bit's with msg = "<< count << endl;
  439.         cout<<"Persent msg in image = "<< count / (double)(N-54) << endl;
  440.     }
  441.  
  442.     char *out = new char[outPath.length() + 1];
  443.     strcpy(out, outPath.c_str());
  444.     fp_out = fopen(out, "wb+");
  445.     ///*Запись в файл*/
  446.     fwrite(image, 1, N, fp_out);
  447.     fclose(fp);
  448.     fclose(fp_out);
  449.     delete [] source;
  450.     delete [] out;
  451.     return 0;
  452. }
RAW Paste Data