Implementación de un sistema de cifrado y descifrado de imágenes digitales con MATLAB


El proyecto ha sido subido a GitHub: dirección del enlace
Mi blog personal: Mouren·Blog
Cuenta pública de Wechat: Saco de Mouren
CSDN: Cao Mouren



Resumen y mapa mental

Este proyecto es un sistema de cifrado y descifrado de imágenes digitales basado en MATLAB, y el algoritmo de cifrado está diseñado de forma independiente por el autor. Este sistema de cifrado puede restaurar la imagen original al 100 % sin pérdidas, admite el cifrado y descifrado de imágenes digitales de un solo canal y de tres canales, y admite el cifrado y descifrado de muchos formatos de imagen convencionales como jpg, jpeg, png, tif, tiff y bmp. Además, los usuarios pueden elegir la cantidad de veces de encriptación, cuantos más tiempos de encriptación, más desordenados estarán los píxeles y mayor será el factor de seguridad. Pero para el destinatario, es conveniente y rápido descifrar la imagen con una clave sin conocer la cantidad de cifrados.
Al mismo tiempo, el algoritmo de este proyecto es simple y fácil de aprender, es un buen proyecto de práctica de procesamiento de imágenes digitales.
El mapa mental general del algoritmo es el siguiente:
mapas mentales

Algoritmo de cifrado de imágenes (con código fuente)

El autor cree que el llamado cifrado es "destrucción regular". Eso es “destruir” lo más posible bajo la premisa de asegurar la recuperación. Cuanto mayor sea el grado de "destrucción", menor será la correlación con la información original, mayor será la dificultad de romperse y mejor será el efecto de cifrado.
Por lo tanto, para "destruir" la imagen original tanto como sea posible, en este sistema de encriptación, el algoritmo de encriptación realiza sucesivamente dos partes: encriptación del valor de píxel y encriptación de distribución de píxeles, "destruyendo" la imagen original desde dos aspectos sucesivamente, y la El efecto de cifrado es mejor.

Cifrado de valor de píxel

El cifrado del valor de píxel se divide en dos pasos.
En el primer paso, dado que el rango de valor de píxel de la imagen de tres canales RBG y la imagen en escala de grises de un solo canal es [0,255], puede restar cada valor de píxel de 255 para realizar la primera conversión de valor de píxel.
La imagen de prueba se ve así:
imagen de prueba

Después del primer paso de transformar el valor del píxel, el resultado es el siguiente:
Después del primer paso del cifrado del valor de píxel

El segundo paso es alterar el orden de los tres canales de RGB y convertir RGB a BRG. Este paso es solo para imágenes RGB de tres canales. Si la imagen entrante es una imagen en escala de grises, solo se completa el primer paso.
En MATLAB, el formato de almacenamiento de la imagen en color de tres canales entrante es una matriz tridimensional de 8 bits enteros sin signo (uint8). El valor del canal R (Rojo) se almacena en (*,*,1), el valor del canal G (Verde) se almacena en (*,*,2) y el valor del canal B (Azul) se almacena en (*,*,3) . Después de la transformación, el valor del canal R (Rojo) se almacena en (*,*,2), el valor del canal G (Verde) se almacena en (*,*,3) y el valor de B ( azul) el canal se almacena en (*, *,1). La siguiente figura es la imagen después del segundo paso de transformación basada en la imagen de salida del primer paso, y también es el resultado del cifrado del valor de píxel de la imagen de prueba:
El cifrado de valor de píxel completa la imagen

Hasta ahora, se ha completado el cifrado del valor de píxel.
Código fuente de la función de transformación de valor de píxel:

function imSrc = Figure_Transform(imSrc,mode)
%该函数对传入图像进行像素值加密或解密
%imSrc:传入三通道或单通道图像
%mode:选择加密或解密。0:加密 1:解密


[~,~,channel]=size(imSrc);%获取传入图像的尺寸信息
%-----------------像素值加密/解密-----------------%
%---step 1:对最大像素值255取差(加密解密相同)---%
imSrc=abs(255-imSrc);

%下面的rgb通道顺序改变只针对3通道图像,单通道灰度图不能进行该操作
if channel==3   
    %---step 2:打乱/恢复 颜色通道顺序---%
    %彩色图像三通道分布顺序:
    %(:,:,1)--red (:,:,2)--green (:,:,3)--blue
    %加密:rgb->brg        解密:brg->rgb
    %---1:前两位交换(加密解密相同)---%
    temp=imSrc(:,:,2);
    imSrc(:,:,2)=imSrc(:,:,1);
    imSrc(:,:,1)=temp;
    %---2:加密:第一位g和第三位b交换得到brg---%
    %---2:解密:第二位b和第三位g交换得到rgb---%
    temp=imSrc(:,:,3);
    imSrc(:,:,3)=imSrc(:,:,1+mode);
    imSrc(:,:,1+mode)=temp;
end


end


Cifrado de distribución de píxeles

A juzgar por la imagen de salida después de que se completa el cifrado del valor del píxel, aunque el color tiene una gran desviación de la imagen original, todavía podemos ver claramente la información de la línea de contorno de la imagen original. Entonces, lo siguiente que tenemos que hacer es alterar el orden de los píxeles y destruir la información del contorno.
Para codificar la disposición de los píxeles, de forma similar a girar el cubo de Rubik, podemos codificar la distribución de píxeles de cada fila y columna sucesivamente. Entonces, ¿qué tipo de reglas de barajado se deben seguir para garantizar el caos y la capacidad de recuperación de la distribución de píxeles? Aquí diseñé una matriz clave: (La siguiente matriz clave es la matriz clave en el sistema actual)
distriKey=

La primera fila de la matriz es el índice, la segunda fila es la clave de compensación de fila y la tercera fila es la clave de la clave de desplazamiento de columna. El signo de la clave secreta determina la dirección del cambio, el valor absoluto determina el grado de cambio y una línea representa un período de traducción. La operación de desplazamiento utiliza la función de desplazamiento circular de MATLAB circshift.
Al realizar el desplazamiento de fila o de columna, dado que los tamaños de las imágenes entrantes son diferentes, para garantizar un efecto de barajado consistente, el valor absoluto del valor clave no puede representar el número de bits de desplazamiento. En su lugar, debe convertirse en la proporción de la columna o fila, por lo que la matriz de la clave secreta debe preprocesarse primero, es decir, el valor absoluto del valor de la clave secreta en la segunda y tercera filas se convierte en la proporción de la fila. , y luego con On the original symbol, el código es el siguiente:

[~,distrikeyCol]=size(distriKey);%获取密钥矩阵尺寸
%下面循环是将密钥值换成比例
for a=1:distrikeyCol
    newRowKey=abs(  distriKey(2,a)  )/ sum( abs( distriKey(2,:) ) );
    newColKey=abs(  distriKey(3,a)  )/ sum( abs( distriKey(3,:) ) );
    %下面是将已经算得的比例值带上原先的正负号
    distriKey(2,a)=newRowKey*(distriKey(2,a)/abs(distriKey(2,a)));
    distriKey(3,a)=newColKey*(distriKey(3,a)/abs(distriKey(3,a)));
end

Después del preprocesamiento, la matriz de clave secreta distriKey=
Matriz de clave secreta preprocesada
¿Cómo obtener el valor de clave secreta correspondiente a la fila o columna actual según el índice de la primera fila?

  • El número de fila o columna actual es módulo la longitud de la matriz de clave secreta
  • Encuentre el mismo valor que el resultado restante en la primera fila de la matriz de clave secreta
  • Después de encontrar el valor del índice correspondiente, la segunda línea de la columna donde se encuentra el índice es el valor de la clave de transformación de la fila y la tercera línea es el valor de la clave de transformación de la columna.

De esta forma, después de tomar el valor de la última columna de la matriz de clave secreta, la próxima vez volverá al valor de la primera columna. Una fila es un ciclo de compensación.
Por lo tanto, podemos aumentar el grado de libertad de migración al aumentar la duración del ciclo de migración y mejorar el factor de seguridad .
A continuación, la imagen después del cifrado del valor de píxel se someterá a una transformación de fila y una transformación de columna:
Después de la transformación de fila:
Después de la transformación de fila

Después de la transformación de fila + transformación de columna:
Después de la transformación de fila + transformación de columna

Hasta ahora, hemos completado el cifrado de valores de píxeles y el cifrado de distribución de píxeles.
Por supuesto, el efecto de cifrado de esta imagen cifrada refleja la matriz de claves que se acaba de enumerar, no la clave óptima.
Podemos cambiar el valor clave y la longitud de la matriz clave para optimizar las reglas de barajado. Por ejemplo:

  • La diferencia entre los valores absolutos de dos valores de clave secreta adyacentes es mayor
  • Los intervalos adyacentes deben evitar el mismo
  • Los signos positivo y negativo del valor de la clave secreta deben establecerse de la forma más irregular posible.
  • Aumentar longitud Aumentar período de compensación
  • ··· ···

Por lo tanto, la matriz de clave secreta aporta mucha libertad al algoritmo de cifrado y no es fácil de descifrar.

Código fuente:
código fuente de la función de transformación de filas:

function imSrc = Row_Transform(imSrc,distriKey,mode)
%   对传入图像进行行变换(加密/解密)
%   imSrc:传入三通道或单通道图像
%   distriKey:传入秘钥矩阵
%   mode:选择加密或解密。 1:加密 -1:解密


[row,col,channel]=size(imSrc);%获取传入图像的尺寸信息
[~,distrikeyCol]=size(distriKey);%获取密钥数组尺寸
%下面循环是将密钥值换成比例
for a=1:distrikeyCol
    newRowKey=abs(  distriKey(2,a)  )/ sum( abs( distriKey(2,:) ) );
    newColKey=abs(  distriKey(3,a)  )/ sum( abs( distriKey(3,:) ) );
    
    distriKey(2,a)=newRowKey*(distriKey(2,a)/abs(distriKey(2,a)));
    distriKey(3,a)=newColKey*(distriKey(3,a)/abs(distriKey(3,a)));
end



%移动的位数和方向由像素分布密钥决定
tempRowMove=zeros(channel,col);
for j=1:row
    %下面循环是将当前行上所有像素值放到中间量tempRowMove中
    for i=1:col
        tempRowMove(:,i)=imSrc(j,i,:);
    end
    %下面选择结构用于判断当前行移动情况(方向和偏移量)
    %在密钥中找到相应秘钥值
    keyId=mod(j,distrikeyCol);
    for m=1:distrikeyCol
            if(distriKey(1,m)==keyId)
                keyId=m;%如果找到keyId位置将该位置的列数赋给keyId
                break;
            end
            continue;
    end
    %确定偏移的方向
    moveDirect=distriKey(2,keyId)/abs(distriKey(2,keyId));
    %偏移量和偏移方向
    rowMove=mode*moveDirect*ceil(row*abs(distriKey(2,keyId)));

    %下面的循环是对当前行上的像素进行移动
    for n=1:channel
        tempRowMove(n,:)=circshift(tempRowMove(n,:),rowMove);
    end
    %下面循环是将偏移后的像素重新赋值回去
    for t=1:col
        for s=1:channel
            imSrc(j,t,s)=tempRowMove(s,t);
        end
    end
end


end


Código fuente de la función de transformación de columnas:

function imSrc = Col_Transform(imSrc,distriKey,mode)
%   对传入图像进行列变换(加密/解密)
%   imSrc:传入三通道或单通道图像
%   distriKey:传入秘钥矩阵
%   mode:选择加密或解密。 1:加密 -1:解密

[row,col,channel]=size(imSrc);%获取传入图像的尺寸信息
[~,distrikeyCol]=size(distriKey);%获取密钥数组尺寸
%下面循环是将密钥值换成比例
for a=1:distrikeyCol
    newRowKey=abs(  distriKey(2,a)  )/ sum( abs( distriKey(2,:) ) );
    newColKey=abs(  distriKey(3,a)  )/ sum( abs( distriKey(3,:) ) );
    
    distriKey(2,a)=newRowKey*(distriKey(2,a)/abs(distriKey(2,a)));
    distriKey(3,a)=newColKey*(distriKey(3,a)/abs(distriKey(3,a)));
end

%移动的位数和方向由像素分布密钥决定
tempColMove=zeros(row,channel);
for j=1:col
    %下面循环是将当前列上所有像素值放到中间量tempColMove中
    for i=1:row
        tempColMove(i,:)=imSrc(i,j,:);
    end
    %下面选择结构用于判断当前列移动情况(方向和偏移量)
    %在密钥中找到相应偏移比例
    keyId=mod(j,distrikeyCol);
    for m=1:distrikeyCol
            if(distriKey(1,m)==keyId)
                keyId=m;%如果找到keyId位置将该位置的列数赋给keyId
                break;
            end
            continue;
    end
    %确定偏移的方向
    moveDirect=distriKey(3,keyId)/abs(distriKey(3,keyId));
    %偏移量和偏移方向
    colMove=mode*moveDirect*ceil(row*abs(distriKey(3,keyId)));
    %下面的循环是对当前列上的像素进行移动
    for n=1:channel
        tempColMove(:,n)=circshift(tempColMove(:,n),colMove);
    end
    %下面循环是将偏移后的像素重新赋值回去
    for t=1:row
        for s=1:channel
            imSrc(t,j,s)=tempColMove(t,s);
        end
    end
end


end


Código fuente de cifrado de distribución de píxeles:
(llame a las funciones de transformación de dos filas y funciones de transformación de columnas anteriores)

function imSrc = Distribution_Transform(imSrc,mode)
%  该函数对传入图像进行像素排列上加密或解密
%  imSrc:传入三通道或单通道图像
%  mode:选择加密或解密。1:加密  -1:解密


%像素分布密钥(第一行是密钥值的索引)
%秘钥的值的绝对值大小就是偏移的程度,正负号表示偏移的方向
%为了保证加密效果,行变换和列变换的秘钥不同
%第二行是行秘钥,第三行是列秘钥
distriKey=[
1,        2,        3,        4,        5,        6,        7,        8,        9,        10,        11,        12,        13,        14,        0;
8,       -1,      -16,      11,      7,        -4,      10,      -4,       12,	     2,	         1,         -20,       -7,         18,        1;
-1,     25,       7,	    -9,	     41,	  -10,	   16,	    -28,	  -2,	   11,	      -10,        6,         45,        -18,       9
];
if mode==1%加密
    imSrc=Row_Transform(imSrc,distriKey,mode);%打乱行
    imSrc=Col_Transform(imSrc,distriKey,mode);%打乱列
else %解密
    imSrc=Col_Transform(imSrc,distriKey,mode);%恢复列
    imSrc=Row_Transform(imSrc,distriKey,mode);%恢复行
end


end

cifrado iterativo de píxeles

Aunque básicamente no tenemos forma de saber cómo se ve la imagen original de la imagen de arriba, podemos ver vagamente que los colores de los píxeles en diferentes áreas son diferentes. Para garantizar un mayor factor de seguridad, podemos realizar un cifrado iterativo de píxeles sin cambiar la matriz de clave secreta .
El cifrado iterativo consiste en repetir el cifrado de distribución de píxeles muchas veces. La razón por la que no se incluye el cifrado del valor del píxel es que si se itera el cifrado del valor del píxel, se restaurará el valor del píxel original, por lo que la iteración no tiene sentido.

Imagen encriptada iterativamente 2 veces:
Iterar 2 veces
Imagen encriptada iterativamente 3 veces:
Iterar 3 veces
Imagen encriptada iterativamente 5 veces:
Iterar 5 veces
A partir de estos resultados, básicamente podemos satisfacer nuestras necesidades de encriptación.
Sin embargo, para descifrar con una clave, no es necesario ingresar el número de descifrados, y la imagen después del cifrado iterativo debe llevar la información del número de iteraciones.
Para que la imagen de salida contenga la información del número de iteraciones, podemos agregar una columna redundante en el extremo izquierdo. El valor de la columna redundante es el mismo que el de la columna adyacente, de modo que la columna redundante pueda ser bien escondido en la imagen encriptada. Luego almacene los tiempos de cifrado en la primera fila, primera columna, primera página, es decir, (1,1,1) de la imagen de salida.
Se puede ver de un vistazo en el siguiente diagrama:
Agregar columnas redundantes
Después de completar el cifrado iterativo, se completa el cifrado de la imagen.
Código fuente de la función de encriptación de imágenes:
(llame a las funciones de encriptación de valor de píxel y encriptación de distribución de píxeles anteriores)

function imSrc = Digital_Image_Encryption(imSrc,count)
%该函数对传入图像进行加密
%imSrc:传入三通道或单通道图像
%count:像素排列加密次数


% %-----------------第一次加密:像素值加密-----------------%
imSrc=Figure_Transform(imSrc,0);%调用封装好的函数

for time=1:count
    %-----------------第二次加密:像素排列加密-----------------%
    imSrc=Distribution_Transform(imSrc,1);
end

%-----------------下面的操作是为了让输出图像携带有加密次数---------------%
[row,~,channel]=size(imSrc);
timesCol=zeros(row,1,channel);
%------为提升安全系数,多出的一列与邻近一列相同,只是第一个像素的像素值是加密次数%
for n=1:row
    timesCol(n,1,:)=imSrc(n,1,:);%将imSrc第一列所有像素复刻到新列中
end
timesCol(1,1,1)=count;%在第一行第一列第一页位置像素值就是加密次数
imOut=[timesCol,imSrc];%将加密次数列并到加密图像上
imSrc=imOut;%将最终图像输出

end

Algoritmo de descifrado de imágenes (con código fuente)

Una vez que se completa el cifrado, el descifrado es simple. El descifrado de imágenes es el proceso inverso al cifrado de imágenes. Existen principalmente los siguientes pasos:

  • El primer paso es obtener la información del número de iteración en (1,1,1) y luego eliminar la primera columna
  • Luego, descifre el valor del píxel, como en el cifrado, primero reste el valor del píxel de 255, si es una imagen de tres canales, luego restaure el orden del canal RGB y convierta BRG nuevamente a RGB
  • Finalmente, descifre la distribución de píxeles. Multiplique -1 en la dirección de desplazamiento para restaurar el mismo número de dígitos en la dirección opuesta a la del cifrado. Establezca un bucle for en la capa exterior. El número de bucles es el número de iteraciones que han ha sido obtenida, por lo que puede ser restaurada imagen original

Descifre la imagen cifrada de forma iterativa 5 veces de la siguiente manera:
descifrar
se puede restaurar sin distorsión.

Código fuente del algoritmo de descifrado de imágenes:
(llame a la función de transformación de valor de píxel y a la función de transformación de distribución de píxeles)

function imSrc = Digital_Image_Decryption(imSrc)
%该函数对传入已加密图像进行解密
%imSrc:传入三通道或单通道图像

count=imSrc(1,1,1);%获取加密次数
imSrc(:,1,:)=[];%删除冗余列
% %-----------------第一次解密:恢复像素值-----------------%
imSrc=Figure_Transform(imSrc,1);%调用封装好的函数

for time=1:count
    %-----------------第二次解密:恢复像素排列-----------------%
    imSrc=Distribution_Transform(imSrc,-1);
end

end

diseño de interfaz de usuario

La interfaz de usuario de este sistema está hecha con APP Designer de MATLAB. La operación específica no se repetirá aquí, la siguiente imagen es la visualización de la interfaz de usuario:

Interfaz de directorio:
interfaz de directorio

Interfaz del sistema de cifrado:
Interfaz del sistema de cifrado

Interfaz del sistema de descifrado:
Interfaz del sistema de descifrado

diseño de logo

Icono de software:
icono
imagen original:
logotipo original

Debido a mi nivel limitado, todavía hay muchas fallas e irracionalidad en el algoritmo y el código, ¡y espero que puedan criticarme y corregirme mucho!

Supongo que te gusta

Origin blog.csdn.net/ZBC010/article/details/121446978
Recomendado
Clasificación