java隐藏图片LSB 算法
import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; public class LSB { //图片宽高 private static int imgHight = 1; private static int imgWidth = 1; private static int imgHight2= 1; private static int imgWidth2 = 1; //像素矩阵集合 private static ArrayList<String[][]> resList = new ArrayList<>(); //原像素矩阵 public static void main(String[] args) throws IOException { //加密 encryption("载体图像.png","秘密图像预处理.png"); //解密 Decrypt("已伪装图像.png"); } /** * 初始化并加密 * @param src 载体图像路径 * @param src2 秘密图像路径 * @throws IOException */ public static void encryption(String src, String src2) throws IOException { System.out.println("载体图像路径:"+src+" 秘密图像路径:"+src2); System.out.println("开始加密...."); //图像操纵对象 BufferedImage imgSrc = ImageIO.read(new File(src)); BufferedImage imgSrc2 = ImageIO.read(new File(src2)); //图片类型 int imgType = 5; imgHight = imgSrc.getHeight(); imgWidth = imgSrc.getWidth(); imgHight2 = imgSrc2.getHeight(); imgWidth2 = imgSrc2.getWidth(); //创建存储像素信息的三个矩阵 resList.clear(); resList.add(ru(imgWidth,imgHight)); resList.add(ru(imgWidth2,imgHight2)); resList.add(ru(imgWidth,imgHight)); //记录载体图像像素信息到第一个矩阵里 for (int i = 0; i < imgWidth; i++) { for (int j = 0; j < imgHight; j++) { resList.get(0)[i][j] = Integer.toBinaryString(imgSrc.getRGB(i, j)); } } //记录秘密图像像素信息到第二个矩阵里 for (int i = 0; i < imgWidth2; i++) { for (int j = 0; j < imgHight2; j++) { resList.get(1)[i][j] = Integer.toBinaryString(imgSrc2.getRGB(i, j)); } } //默认从左上角开始隐藏 for (int i = 0; i < imgWidth; i++) { //如果小于隐藏图像的宽度,列号 if (i<imgWidth2){ for (int j = 0; j < imgHight; j++) { //且小于隐藏图像的高度,行号 //则为秘密图像的宽高范围,应发生置换 if (j<imgHight2){ char[] chars1 = resList.get(0)[i][j].toCharArray(); char[] chars3 = chars1; char[] chars2 = resList.get(1)[i][j].toCharArray(); //就将对应的位置信息放置在对应像素的透明度、红、绿、蓝通道的低4bit位 //采用U型替换规则,加密顺时针替换,解密逆时针替换 //蓝通道 chars3[31] = chars2[24]; chars3[30] = chars2[25]; chars3[29] = chars2[26]; chars3[28] = chars2[27]; //绿通道 chars3[23] = chars2[16]; chars3[22] = chars2[17]; chars3[21] = chars2[18]; chars3[20] = chars2[19]; //红通道 chars3[15] = chars2[8]; chars3[14] = chars2[9]; chars3[13] = chars2[10]; chars3[12] = chars2[11]; //透明度通道 chars3[7] = chars2[0]; chars3[6] = chars2[1]; chars3[5] = chars2[2]; chars3[4] = chars2[3]; //保存置换后的像素信息至第三个矩阵中 resList.get(2)[i][j] = String.valueOf(chars3); }else { //保存没有置换的像素信息至第三个矩阵中 resList.get(2)[i][j] = String.valueOf(resList.get(0)[i][j].toCharArray()); } } }else { for (int j = 0; j < imgHight; j++) { resList.get(2)[i][j] = String.valueOf(resList.get(0)[i][j].toCharArray()); } } } //输出加密结果 oimg(resList.get(2),"已伪装图像",imgWidth,imgHight); System.out.println("加密完成...."); } public static void Decrypt(String src) throws IOException { //图像操纵对象 BufferedImage imgSrc = ImageIO.read(new File(src)); //图片类型 int imgType = 5; imgWidth = imgSrc.getWidth(); imgHight = imgSrc.getHeight(); System.out.println(imgWidth2); System.out.println(imgHight2); resList.clear(); resList.add(ru(imgWidth,imgHight)); resList.add(ru(imgWidth2,imgHight2)); for (int i = 0; i < imgWidth; i++) { if (i<imgWidth2){ for (int j = 0; j < imgHight; j++) { if (j<imgHight2){ char[] chars1 = Integer.toBinaryString(imgSrc.getRGB(i, j)).toCharArray(); char[] chars2 = new char[32]; char[] chars3 = new char[32]; for (int h = 0; h < 32; h++){ chars2[h] = '0'; chars3[h] = '0'; } chars2[24] = chars1[24]; chars2[25] = chars1[25]; chars2[26] = chars1[26]; chars2[27] = chars1[27]; chars3[24] = chars1[31]; chars3[25] = chars1[30]; chars3[26] = chars1[29]; chars3[27] = chars1[28]; chars2[16] = chars1[16]; chars2[17] = chars1[17]; chars2[18] = chars1[18]; chars2[19] = chars1[19]; chars3[16] = chars1[23]; chars3[17] = chars1[22]; chars3[18] = chars1[21]; chars3[19] = chars1[20]; chars2[8] = chars1[8]; chars2[9] = chars1[9]; chars2[10] = chars1[10]; chars2[11] = chars1[11]; chars3[8] = chars1[15]; chars3[9] = chars1[14]; chars3[10] = chars1[13]; chars3[11] = chars1[12]; chars2[0] = chars1[0]; chars2[1] = chars1[1]; chars2[2] = chars1[2]; chars2[3] = chars1[3]; chars3[0] = chars1[7]; chars3[1] = chars1[6]; chars3[2] = chars1[5]; chars3[3] = chars1[4]; resList.get(0)[i][j] = String.valueOf(chars2); resList.get(1)[i][j] = String.valueOf(chars3); }else { resList.get(0)[i][j] = Integer.toBinaryString(imgSrc.getRGB(i, j)); } } }else { for (int j = 0; j < imgHight; j++) { resList.get(0)[i][j] = Integer.toBinaryString(imgSrc.getRGB(i, j)); } } } oimg(resList.get(0),"解密后载体图像",imgWidth,imgHight); oimg(resList.get(1),"解密后秘密图像",imgWidth2,imgHight2); System.out.println("解密完成...."); } /** * 生产像素矩阵 * @param width * @param hight * @return */ public static String[][] ru(int width,int hight){ return new String[width][hight]; } /** * 图片输出方法 * @param matrix * @param name * @param imgWidth * @param imgHight */ public static void oimg(String[][] matrix, String name,int imgWidth, int imgHight){ BufferedImage imgRes = new BufferedImage(imgWidth, imgHight, 5); for (int i = 0; i < imgWidth; i++) { for (int j = 0; j < imgHight; j++) { // System.out.println("第"+name+"个 i:"+i+" j:"+j+" 值:"+Integer.parseUnsignedInt(r[i][j],2)); imgRes.setRGB(i,j,Integer.parseUnsignedInt(matrix[i][j],2)); } } File imgOut = new File("img/zui10/"+name+".png"); //输出文件 try { ImageIO.write(imgRes, "png", imgOut); } catch (IOException e) { e.printStackTrace(); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)