目标学了三天、说三遍
base64编码与隐写、base64编码与隐写、base64编码与隐写
* 代码实现 *
1. base64编码规则:
- 3个字符转换成4个字符
- 每76个字符加一个换行符
- 最后的结束符也要处理
2. base64编码码值:
A ~ Z、 a ~ z、0 ~ 9、+、/
一共64个字符,用这64个字符来加密文本字符。
64位只需要 (100000)b=64
6位二进制即可表示0~63这64个字符。
3.例子:对 (LOVE) 加密之后是 (TE9WRQ==)
可以看出A区补的是0,这里补1也可以,原因是因为不管补的是0还是1,都不会影响原文本E的值,那么这里就可以补 24 种情况。
这样,就知道了,后面需要补位的地方就可以用来隐写一些东西。
根据6、8倍数的关系,他们后面都可以通过补8、16位 01.对于补充的加密为‘=’。但是注意=不能用1来补位,因为这样就会改变原文本的值。
那么就可以知道
- 一个等号,就会有4位可以隐写的空间
- 两个等号,就会有2位可以隐写的空间
通过解释就可以用代码来练习练习。
当然这些都不需要你知道。因为PHP、py、Java……都封装好了,可以直接调用,这里不说,抵住诱惑。
但是为了加深理解,用c++来实现。
4. base64编码使用 :https://blog.csdn.net/qq_44009311/article/details/102755057#11
5. 代码如下:思路就是上面解释的二进制转换规律
下面写了解密的代码,加密都是类似的。
-
base64解密 一个文件内的字符串
#include<bits/stdc++.h> #define f(i,a,b) for(int (i)=(a);(i)<(b);(i)++) #define _f(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) using namespace std; map<char,int> v; ifstream in("a.txt");//path路径 string str="",str_01="",result=""; int main() { for(int i='A'; i<='Z'; i++) v[i]=i-'A'; for(int i='a'; i<='z'; i++) v[i]=i-'a'+26; for(int i='0'; i<='9'; i++) v[i]=i-'0'+52; v['+']=62,v['/']=63,v['=']=0; printf("解密文本:\n"); while(str=str_01=result="",getline(in,str)) { f(i,0,str.length()) _f(j,5,0) str_01+=('0'+((v[str[i]]>>j)&1)); for(int i=0,b=0; i<str_01.length(); result+=b,b=0,i+=8) _f(j,7,1) b|=((str_01[i+j]-'0')<<(7-j)); f(i,0,result.length()) printf("%c",result[i]); puts(""); } in.close(); return 0; }
-
在base64中找出 隐写的 flag
#include <iostream> #include <map> #include <string> #include <fstream> #define f(i,a,b) for(int (i)=(a);(i)<(b);(i)++) #define _f(i,a,b) for(int (i)=(a);(i)>=(b);(i)--) using namespace std; int main() { ifstream in("stego.txt");//把文本保存在a.txt map<char,int> v; // 存储字符对应的base64编码 f(i,'A','Z'+1) v[i]=i-'A'+0; f(i,'a','z'+1) v[i]=i-'a'+26; f(i,'0','9'+1) v[i]=i-'0'+52; v['+']=62,v['/']=63,v['=']=64; string str="", str_01=""; //记录每行的字符串,每行文本对应的二进制 for(int d[4]; getline(in,str); ) { _f(i,3,1) d[i]=v[str[str.length()-i]]; //取出每行的倒数三个 if(d[1] == 64) //从后面对第一个不为等号的字符进行提取,解码时1个字符对应6位二进制 if(d[2] == 64) _f(i,3,0) str_01+=('0'+((d[3]>>i)&1)); //末尾两个等号,说明倒数第三位字符有4位空间可以隐藏flag else _f(i,1,0) str_01+=('0'+((d[2]>>i)&1)); //末尾有一个等号,说明倒数第二位字符有2位空间可以隐藏flag } printf("flag:\n"); for(int i=0,b=0; i<str_01.length(); printf("%c", b), b=0, i+=8) //把保存的二进制进行解析 _f(j,7,1) b|=((str_01[i+j]-'0')<<(7-j)); //8位二进制对应1位字符 printf("\n"); return 0; }
滴滴、、、滴滴答