自己学习制作代码,用来读取图片像素方式加密的信息,加密格式为Unicode中文16进制。
去掉\u 的纯16进制。
//读取图片中rpg值,解密信息
public static void main(String[] args) throws Exception {
//图片地址,绝对路径 如 D:\testAA.png
String url = "D:\\testAA.png";
File file = new File(url);
BufferedImage BI = null;
try {
BI = ImageIO.read(file);
} catch (Exception e) {
e.printStackTrace();
}
int width = BI.getWidth();
int height = BI.getHeight();
int minx = BI.getMinX();
int miny = BI.getMinY();
int[] rgb = new int[3];
ArrayList<Integer> testarrayA=new ArrayList<>();
for (int i = minx; i < width; i++) {
for (int j = miny; j < height; j++) {
int pixel = BI.getRGB(i, j);//获得像素值
rgb[0] = (pixel & 0xff0000) >> 16;
rgb[1] = (pixel & 0xff00) >> 8;
rgb[2] = (pixel & 0xff);
//记录加密信息,用array数组,不要用string拼接字符串,那会超级慢。
/*
* 知识点,string拼接,底层是copy一个原char数组,然后再加上新值,再转成sting的。所以直接用数组就可以了
* 这个程序,如果这里用string拼接将导致,一秒一次外循环,甚至一秒以上,这个外循环要几千次,等不起的
* 用了array数组,几秒就执行完成,效率高了无数倍。
* */
for(int n=0;n<3;n++){
if (rgb[n] % 2 == 1) {
testarrayA.add(1);
}else{
testarrayA.add(0);
}
}
}
}
String bianliang =String.valueOf(testarrayA.subList(0,testarrayA.size()-1));
bianliang=bianliang.replace(",","");
bianliang=bianliang.replace("[","");
bianliang=bianliang.replace("]","");
bianliang=bianliang.replace(" ","");
String bianliangA= erzhuanshiliu(bianliang);
String yuanwen=decodeUnicode(bianliangA);
System.out.println(yuanwen);
}
/*
* 二进制转十六进制
*/
public static String erzhuanshiliu(final String bianliang) {
//这里也是要用数组,不然会很慢。
ArrayList<String> hex=new ArrayList<>();
for(int i=0;i<bianliang.length()/16;i++){
int commDec = Integer.valueOf(bianliang.substring(i*16,i*16+16),2);
hex.add("\\u");
hex.add(Integer.toHexString(commDec));
}
String request =String.valueOf(hex.subList(0,hex.size()-1));
request=request.replace(",","");
request=request.replace("[","");
request=request.replace("]","");
request=request.replace(" ","");
return request;
}
/*
* unicode编码转中文
*/
public static String decodeUnicode(final String dataStr) {
int start = 0;
int end = 0;
final StringBuffer buffer = new StringBuffer();
while (start > -1) {
end = dataStr.indexOf("\\u", start + 2);
String charStr = "";
if (end == -1) {
charStr = dataStr.substring(start + 2, dataStr.length());
} else {
charStr = dataStr.substring(start + 2, end);
}
if(charStr.equals("")){
charStr="0";
}
char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。
buffer.append(new Character(letter).toString());
start = end;
}
return buffer.toString();
}
浅谈制作中遇到的问题
问题一,刚开始用的string字符串拼接,导致速度慢的要死,读取要跑个半个点,,后面改成数组
几秒钟就跑完。搜了才知道,和string的底层有关,string字符串拼接的原因。(基础知识太不牢固了)。
问题二,进制转换,有现成可以直接调用的不知道是啥,还自己写,写完了百度才发现又现成的。
问题三,Unicode转中文的时候,发现charStr莫名其妙为"",所以加了个判断,不知道是不是我哪里写的有问题。
问题四,pixell & 0xff0000 这个开始我是真没看懂怎么就能转成像素值了。后面百度了下,才稍微明白点,但还是很懵。
最后,比较好奇,这种加密信息的方式,真的有人用么,破解的话因该也很好破解吧。
我现在想到用这种加密比较安全的就是,16进制的长串密码进行算法加密比如AES128,加密后的值再加密到图片上。但是一旦原图片丢失,或者损毁,感觉信息恢复都没法恢复那种,尤其是现在好多快捷发送图片的都会对图片进行压缩,或者处理。只能是选择文件发送。