base64编码和解码是一个常用的方式,可以避免明文传输或者存储,也可以结合加解密技术进行使用。
public class Test {
private final static char pem_array[] = {
// 0 1 2 3 4 5 6 7
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+','/' // 7
};
private final static byte pem_convert_array[] = new byte[256];
static {
for (int i = 0; i < 255; i++) {
pem_convert_array[i] = -1;
}
for (int i = 0; i < pem_array.length; i++) {
pem_convert_array[pem_array[i]] = (byte) i;
}
}
/**
* @param str 待编码字符串
* @return base64 编码字符串
*/
static String getBase64FromStr(String str){
String strToTwo = strToTwo(str);
StringBuilder base64Str=new StringBuilder(str.length());
for (int i = 0,len=strToTwo.length(); i <strToTwo.length() ; i=i+6) {
if(i+6>len){
String sub = strToTwo.substring(i, len);
int count=0;
while (sub.length()<6){
sub=sub+"0";
count++;
}
base64Str.append(pem_array[Integer.parseInt(sub,2)]);
if(count>2)return base64Str.append("==").toString();
return base64Str.append("=").toString();
}
String sub = strToTwo.substring(i, i + 6);
base64Str.append(pem_array[Integer.parseInt(sub,2)]);
}
return base64Str.toString();
}
/**
* @param str base64编码字符串
* @return base64解码字符串
*/
static String getStrFromBase64(String str){
int len = str.length();
char[] chars = str.toCharArray();
StringBuilder resStr=new StringBuilder(len);
for (int i = 0; i <len ; i++) {
if(chars[i]!='='){
int res=Test.pem_convert_array[chars[i]];
String binStr = Integer.toBinaryString(res);
while (binStr.length()<6)binStr="0"+binStr;
resStr.append(binStr);
}
}
int length = resStr.length();
StringBuilder retStr = new StringBuilder(len);
for (int i = 0; i +8<= length; i=i+8) {
String subStr = resStr.substring(i, i + 8);
retStr.append((char)Integer.parseInt(subStr,2));
}
return retStr.toString();
}
static String strToTwo(String str){
char[] chars = str.toCharArray();
StringBuilder res=new StringBuilder(chars.length*8);
for (int i = 0,len=chars.length; i <len ; i++) {
String binStr = Integer.toBinaryString(chars[i]);
while(binStr.length()<8)binStr="0"+binStr;
res =res.append(binStr);
}
return res.toString();
}
}
需要隐藏的who的ASCII码的二进制:0111 0111 01101000 01101111
H的base64编码:SA==
需要隐藏的二进制:0111 0111 0110 1000 0110 1111
故隐写后的base64编码如下:
SH==
SH==
SG==
SI==
SG==
SP==
给出一个base64隐写解码的java方法:
public class Test {
private final static char pem_array[] = {
// 0 1 2 3 4 5 6 7
'A','B','C','D','E','F','G','H', // 0
'I','J','K','L','M','N','O','P', // 1
'Q','R','S','T','U','V','W','X', // 2
'Y','Z','a','b','c','d','e','f', // 3
'g','h','i','j','k','l','m','n', // 4
'o','p','q','r','s','t','u','v', // 5
'w','x','y','z','0','1','2','3', // 6
'4','5','6','7','8','9','+','/' // 7
};
private final static byte pem_convert_array[] = new byte[256];
static {
for (int i = 0; i < 255; i++) {
pem_convert_array[i] = -1;
}
for (int i = 0; i < pem_array.length; i++) {
pem_convert_array[pem_array[i]] = (byte) i;
}
}
public static void main(String[] args) {
String steTxt="SH==\n" +
"SH==\n" +
"SG==\n" +
"SI==\n" +
"SG==\n" +
"SP==";
getSteFromBase64(steTxt);
}
/**
*
* @param stegotextBase64 含隐写的base64加密串
* @return 隐写的字符串
*/
static String getSteFromBase64(String stegotextBase64) {
String[] split = stegotextBase64.split("\n");
Decoder decoder = Base64.getDecoder();
StringBuilder base64Str = new StringBuilder(stegotextBase64.length());
String reSub = "";
for (int j = 0, len = split.length; j < len; j++) {
String stegb64 = split[j];
String rowb64 = getBase64FromStr(getStrFromBase64(stegb64));
String reStegb64 = stegb64.replace("=", "");
String reRowb64 = rowb64.replace("=", "");
int offset = Math.abs(pem_convert_array[reStegb64.toCharArray() [reStegb64.length() - 1]]
- pem_convert_array[reRowb64.toCharArray()[reRowb64.length() - 1]]);
int count = stegb64.length() - reStegb64.length();
if (count > 0) {
String binStr = Integer.toBinaryString(offset);
while (binStr.length() < count * 2) binStr = "0" + binStr;
reSub = reSub + binStr;
}
}
int length = reSub.length();
String retStr = "";
for (int j = 0; j + 8 <=length; j = j + 8) {
retStr = retStr + (char) Integer.parseInt(reSub.substring(j, j + 8), 2);
}
System.out.println(retStr);
return retStr;
}
}
根据上述过程给出一个可以自己写一个隐写的方法。
总结一下:base64编码原理就是通过使用base64编码表将8位二进制位表示的字符串编码为6位表示的base64编码表的字符,不够6的倍数的通过补充0的方式补足6位,补0的个数用=号表示,一个=代表补两个二进制位0,故经过base64编码后3个8位表示的ASCII 字符就变成了4位base64编码。
解码原理:base64字符串按照base64编码表转换为6位二进制位,然后拼接成字符串,将二进制字符串从前到后按8位进行转换为对应的ASCII码字符,最后不足8位的丢弃即可。
隐写原理:通过base64编码解码原理可以得出:补0的部分不影响解码,故可以利用这些补的二进制位0进行隐写,即将需要隐写的字符串转换为二进制位,去替换补0的部分,达成隐写的目的。一行base64编码最多两个=号,那么只能隐写4位二进制位,隐写字符串就需要很长的base64编码行。
本文地址:https://blog.csdn.net/m0_37948170/article/details/107387926
如对本文有疑问, 点击进行留言回复!!
sap cloud platform destination的配置
springcloud中feign调用处理mybatis-plus Ipage反序列化问题。
Flume 史上最全面的大数据学习第十篇(一) 别再说不知道flume是什么了
网友评论