⑴ matlab 提高函數速度
temp = bin2dec(reshape(data, 16, 8));
這樣試試看
不是所有for循環都可以去掉
難道我的回答第一句代碼是隱形的嘛?。。。就是讓你用這句替換掉for循環啊 當然這個結果是列向量,可能需要轉置一下什麼的
⑵ 一個matlab程序加密後只能通過密碼或者生成密鑰來運行程序如何實現
n=4;%%%設定允許輸入密碼的次數即可。
⑶ 求一個加密解密演算法實作(C++或matlab)
welcome to guangzhou hongmeng !
import java.io.*;
public class suanfa1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成方法存根
File file=new File("1.txt");
System.out.println(file.length()/12);
int x[]=new int[3];
try{
BufferedReader in=new BufferedReader(new FileReader(file));
char xxx[][]=new char[1000][4];
int i=0;
while(in.read(xxx[i])==4)
{
i++;
}
int j=i,xy=0;
suanfa2 xx[]=new suanfa2[j/3];
for(i=0;i<j;i+=3,xy++)
{
for(int k=i,xz=0;k<i+3;k++,xz++)
x[xz]=Integer.parseInt(new String(xxx[k]));
xx[xy]=new suanfa2(x[0],x[1],x[2]);
//System.out.println("實際位置:"+xx[xy].wei1);
System.out.print(xx[xy].zifu1);
}
suanfa1.sort1(xx);
for(i=0;i<xy;i++)
System.out.print(xx[i].zifu1);
}
catch(IOException e){}
}
public static void sort1(suanfa2 xyz[])
{
int length=xyz.length;
for(int x=1;x<length;x++)
{
int k=x-1;
for(int i=x;i<length;i++)
if(xyz[i].wei1<xyz[k].wei1)
{
suanfa2 xx;
xx=xyz[i];
xyz[i]=xyz[k];
xyz[k]=xx;
}
}
}
}
public class suanfa2 {
int suanzi;//加密運算元
int wei;//表示這個字元在整個字元串中的位置(加密),
int zifu;//表示加密過的字元(ASCII碼值)。
char zifu1;//被加密的字元
int wei1;//實際的位置
public suanfa2(int x,int y,int z)
{
// TODO 自動生成構造函數存根
this.suanzi=x;
this.wei=y;
this.zifu=z;
wei1=this.getSJwei();
zifu1=this.getZifu();
}
int getSJwei()
{
return wei-suanzi;
}
char getZifu()
{
return (char)(zifu+suanzi);
}
}
1.txt
48-016--019---01600130048-01800120051006800680051
⑷ MATLAB Compiler Runtime怎麼用
使用MATLAB Compiler
(一)准備
什麼是MATLAB Compiler?MATLAB Compiler能夠將你的matlab程序轉換為自包含(self-contained)的應用程序和組件,這樣你就可以將程序發放給你的終端用戶,而且終端用戶無需安裝matlab就可以運行這些程序。MATLAB Compiler能夠生成的應用或者組件包括下面這幾類:
1、獨立的應用程序
2、C和C++共享庫(動態鏈接庫,在Windows平台上是DLL,在Linux平台下是.so文件)
3、Excel插件
4、COM和.NET對象
本文中我們只看matlab是如何生成獨立的應用程序的。其他組件生成方式可以參考matlab的幫助文檔。注意:在你使用MATLAB Compiler和閱讀相關說明文檔之前,要求你一定要已經安裝了MATLAB Compiler,也就是安裝的時候必須要選中MATLAB Compiler復選框。在我使用的matlab 2005a上,安裝的是MATLAB Compiler version 4。
假定你已經安裝好了MATLAB Compiler。下面我們看一下與MATLAB Compiler相關的兩個重要概念MCR和CTF。
MCR的全稱是MATLAB Component Runtime,它是一組獨立的共享庫,通過它能夠執行在MATLAB中編寫的M文件。MCR支持MATLAB語言的所有功能。
CTF的全稱是Component Technology File,這是一種歸檔技術,通過它,MATLAB將可部署文件包裝起來。需要注意的是,位於CTF歸檔文件中的所有M文件都採用了AES(Advanced Encryption Standard)進行加密,AES的對成密鑰則通過1024位的RSA密鑰保護。除此之外,CTF還對歸檔文件進行了壓縮。顯然,通過這種方式,可以只將可知行的應用程序或者組件發布給終端用戶,而保證源代碼不被泄漏。
MATLAB Compiler的構建過程分為下面五步:
1、分析依賴關系
2、代碼生成
3、創建歸檔文件(archive)
4、編譯
5、鏈接
事實上,只有前面三步是針對M文件的,第四步和第五步和通常編譯C或者C++程序毫無二致。因此,你可能會想到,這不就能夠混合使用MATLAB和C以及C++了么?是的。MATLAB Compiler可以讓你很簡單很容易地做到這一點,不過這並不是本文要講述的內容。
既然MATLAB Compiler是將M文件中的代碼編譯成C/C++介面,那麼應該使用什麼樣的C/C++編譯器呢?MATLAB Compiler支持的ANSI C和C++編譯器有這樣一些:
1、Lcc C version 2.4.1,這個是MATLAB Compiler自帶的編譯器,也是默認的編譯器,但是它只能支持C代碼;
2、Borland C++ version 5.5,5.6,以及5.5免費版
3、Microsoft Visual C/C++(MSVC)version 6.0和7.1
4、對於UNIX系統,支持的編譯器是gcc和g++
(二)開始
要使用MATLAB Compiler,在MATLAB的command窗口或者DOS命令窗口輸入mcc即可。比如,我們在MATLAB的command窗口下輸入(本文中以加色的字元表示交互信息):
>> mcc
將會出現:
Error: No source files were specified (-? for help).
??? Error executing mcc, return status = 1.
這里的提示表明一定要給mcc指定源代碼文件,也即使已經寫好的M文件。你也可以輸入:
>> mcc -?
或者:
>> help mcc
來獲取mcc的幫助信息。當然,詳盡的幫助文檔應該參考MATLAB Help。
這里以我在上一篇日誌中給出的write_dicom.m文件為例進行說明:
如果要生成獨立的應用程序,那麼只需要在MATLAB的command窗口或者DOS命令窗口輸入:
>> mcc -m write_dicom
即可。如果要生成動態鏈接庫,那麼只需要將選項改為:
>> mcc -l write_dicom
即可。
注意,必須要確保write_dicom.m在MATLAB的當前工作目錄下。否則會出錯。
假設我現在是想生成獨立的應用程序,那麼在執行了:
>> mcc -m write_dicom
之後(在我的機器上這個過程可能需要一分鍾左右,有點慢)。在當前工作目錄下會多出這樣一些文件:
write_dicom_main.c
write_dicom_mcc_component_data.c
write_dicom.ctf
write_dicom.exe
其中,write_dicom_main.c中是包裹函數,write_dicom_mcc_component_data.c中包含了解壓write_dicom.ctf的數據(如密鑰等)。而write_dicom.exe則是我們可以直接運行的應用程序,很遺憾,這里我們只能通過DOS命令窗口對它進行調用,不過這對於我們而言並沒有什麼,不是么?接下來,我們打開DOS命令窗口,切換到MATLAB的工作目錄下面(也就是這里生成出來的幾個文件所在的目錄)。然後在命令行下輸入:
C:\matlab2006\work>write_dicom ya.jpg ya.dcm
Extracting CTF archive. This may take a few seconds, depending on the
size of your application. Please wait...
...CTF archive extraction complete.
C:\matlab2006\work>
可以看到,write_dicom先從write_dicom.ctf抽取出相關的文件,注意到抽取完成之後在當前目錄下會多出一個write_dicom_mcr\文件夾來。在這個文件夾中,不僅包含了原來的程序文件write_dicom.m,還包括了toolbox\下與DICOM讀寫等有關的M文件,但是這些文件都已經被加密了,直接用MATLAB Editor是看不到文件的真正內容的,出來的是一堆毫無意義的亂碼。
上面的程序執行起來同樣比較慢,不過,只要它能正確執行,誰在乎這點時間呢?況且我的機器配置並不好^_^
可以看到,此時,ya.dcm已經生成了,就在C:\matlab2006\work\目錄下,我們同樣可以用CVIEW.exe等等DICOM工具查看圖像或者查看DICOM元數據(metadata)。
⑸ 基於AES的文件加密管理系統的實現。要求具有良好的交互界面!實現對文件(txt,word,excel等文件)的加密。
#ifndef uint8
#define uint8 unsigned char
#endif
uint8 sbox[256]={
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};
uint8 invsbox[256] =
{
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
};
class Rijndeal
{
public:
char text[1000],text1[1000];
uint8 state[16];
uint8 key[16];
uint8 roundkey[11][16];
void add(uint8 s[16],uint8 k[16]);
void subbyte(uint8 s[16]);
void shiftrows(uint8 s[16]);
void mixcolumns(uint8 s[16]);
void keysehele();
void rijndeal();//加密
void jiami();
void invsubbyte(uint8 s[16]);
void invshiftrows(uint8 s[16]);
void invmixcolumns(uint8 s[16]);
void invrijndeal();
void jiemi();
};
void Rijndeal::add(uint8 s[16],uint8 k[16])
{
for(uint8 i=0;i<16;i++)
s[i]^=k[i];
}
void Rijndeal::subbyte(uint8 s[16])
{
for(int i=0;i<16;i++)
s[i]=sbox[s[i]];
}
void Rijndeal::shiftrows(uint8 s[16])
{
int i,t=s[4];
for(i=4;i<7;i++)s[i]=s[i+1];
s[i++]=t;
t=s[i];s[i]=s[i+2];s[(i++)+2]=t;
t=s[i];s[i]=s[i+2];s[i+2]=t;
t=s[15];
for(i=15;i>12;i--)s[i]=s[i-1];
s[i]=t;
}
void Rijndeal::mixcolumns(uint8 s[16])
{
int i;
uint8 mix[4][4]={2,3,1,1,1,2,3,1,1,1,2,3,3,1,1,2};
uint8 ss[16];
for(i=0;i<16;i++)ss[i]=s[i];
for(i=0;i<4;i++)
for(int j=0;j<4;j++)
{
int f[4];
for(int l=0;l<4;l++)
{
f[l]=ss[i+4*l];
if(mix[j][l]==2)f[l]<<=1;
if(mix[j][l]==3)f[l]^=f[l]<<1;
if(f[l]&0x100)f[l]^=0x11b;//溢出時要異或0x11b
}
s[4*j+i]=((uint8)f[0])^((uint8)f[1])^((uint8)f[2])^((uint8)f[3]);
}
}
void Rijndeal::keysehele()
{
uint8 bit[10]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x1b,0x36};
int i;
for(i=0;i<16;i++)roundkey[0][i]=key[i];
for(i=1;i<=10;i++)
{
for(int j=0;j<4;j++)
{
uint8 f[4];
if(j==0)
{
for(int l=0;l<4;l++)
f[l]=roundkey[i-1][3+l*4];
uint8 t=f[0];
for(l=0;l<3;l++)f[l]=f[l+1];
f[l]=t;
for(l=0;l<4;l++)f[l]=sbox[f[l]];
roundkey[i][0]=roundkey[i-1][0]^f[0]^bit[i-1];
for(l=1;l<4;l++)roundkey[i][l*4]=roundkey[i-1][l*4]^f[l];
}
else for(int l=0;l<4;l++)
roundkey[i][j+l*4]=roundkey[i][j+l*4-1]^roundkey[i-1][j+l*4];
}
}
}
void Rijndeal::rijndeal()//組加密
{
keysehele();
add(state,roundkey[0]);
for(int i=1;i<10;i++)
{
subbyte(state);
shiftrows(state);
mixcolumns(state);
add(state,roundkey[i]);
}
subbyte(state);
shiftrows(state);
add(state,roundkey[i]);
}
void Rijndeal::jiami()
{
int l=0,k=0,i;
for(i=0;i<16&&text[i]!='\0';i++)key[i]=text[i];//把明文的前16個當做初始密鑰
if(i<16)for(;i<16;i++)key[i]=' ';//不夠16位補空隔
while(text[l]!='\0')
{
for(i=0;i<16&&text[l]!='\0';i++,l++)state[i]=text[l];//分組
if(i<16)for(;i<16;i++)state[i]=' ';//分組不夠16位,按空隔處理
rijndeal();
for(i=0;i<16;i++)
text1[k++]=state[i];
}
text1[k]=NULL;
cout<<"\n輸出加密後的數據:\n";
cout<<"\N";
}
void Rijndeal::invsubbyte(uint8 s[16])
{
for(int i=0;i<16;i++)
s[i]=invsbox[s[i]];
}
void Rijndeal::invshiftrows(uint8 s[16])
{
int i,t;
t=s[7];
for(i=7;i>4;i--)s[i]=s[i-1];
s[4]=t;
t=s[8];s[8]=s[10];s[10]=t;
t=s[9];s[9]=s[11];s[11]=t;
t=s[12];
for(i=12;i<15;i++)s[i]=s[i+1];
s[15]=t;
}
void Rijndeal::invmixcolumns(uint8 s[16])
{
int i;
uint8 invmix[4][4]={14,11,13,9,9,14,11,13,13,9,14,11,11,13,9,14};
uint8 ss[16];
for(i=0;i<16;i++)ss[i]=s[i];
for(i=0;i<4;i++)
for(int j=0;j<4;j++)
{
int f[4];
for(uint8 l=0;l<4;l++)
{
f[l]=ss[i+4*l];
int a,b,c;
a=(uint8)f[l]<<1;
if(a&0x100)a^=0x11b;
b=a<<1;
if(b&0x100)b^=0x11b;
c=b<<1;
if(c&0x100)c^=0x11b;
if(invmix[j][l]==9)
f[l]=f[l]^c;
else if(invmix[j][l]==11)
f[l]=f[l]^a^c;
else if(invmix[j][l]==13)
f[l]=f[l]^b^c;
else if(invmix[j][l]==14)
f[l]=a^b^c;
}
s[4*j+i]=f[0]^f[1]^f[2]^f[3];
}
}
void Rijndeal::invrijndeal()//組解密
{
add(state,roundkey[10]);
invshiftrows(state);
invsubbyte(state);
for(int i=9;i>0;i--)
{
add(state,roundkey[i]);
invmixcolumns(state);
invshiftrows(state);
invsubbyte(state);
}
add(state,roundkey[0]);
}
void Rijndeal::jiemi()
{
int l=0,k=0,i;
while(text1[l]!=NULL)
{
for(i=0;i<16;i++,l++)
state[i]=text1[l];
invrijndeal();
for(i=0;i<16;i++)
text[k++]=state[i];
}
text[k]='\0';
while(text[k-1]==' ')text[(k--)-1]='\0';
cout<<"\n解密後得明文為:\n"<<"\N";
}
int main()
{
Rijndeal C;
gets(C.text);
C.jiami();
C.jiemi();
return 0;
}
就不發GUI的了 GUI的麻煩
⑹ 各位大俠,急求AES圖像加密的MATLAB代碼!!!
首先說定義的函數可能在調用時出現問題,原因是函數的輸入部分plot在其中並沒有使用,再者輸出參數應包括m和n,因此函數定義部分應該改為function
[hist,
rgbt,m,n]
=
getimagehists(imagename)。
在執行完hist
=
hist
/
(m*n),執行如下語句完成數據保存
save
hists.mat
hist
接著可以執行
clear
all
並執行
load
hists.mat
hist
及whos
以驗證數據存儲是否成功
⑺ 懂MATLAB和AES加密演算法的高手來幫我!怎麼用MATLAB語言編程AES加密演算法
加密過程為:C=Ek3(Dk2(Ek1(P)))
3DES解密過程為:P=Dk1((EK2(Dk3(C)))
具體的加/解密過程如圖2所示。K1、K2、K3決定了演算法的安全性,若三個密鑰互不相同,本質上就相當於用一個長為168位的密鑰進行加密。多年來,它在對付強力攻擊時是比較安全的。若數據對安全性要求不那麼高,K1可以等於K3。在這種情況下,密鑰的有效長度為112位。
⑻ 初學者,求高手給一個完整的AES加密解密演算法的程序(C/C++) 希望能滿足如下要求
/*128bits密鑰長度及分組長度AES加解密代碼
*作者:Jeffrey.zhu
*/
⑼ 求AES加解/密碼密軟體程序!!!
有界面,我這里有個,但是是c#語言的,你以為如何?
下面是c版本的
AES加密演算法源代碼
//AES.h
#define decrypt TRUE
#define encrypt FALSE
#define TYPE BOOL
typedef struct _AES{
int Nb;
int Nr;
int Nk;
unsigned long *Word;
unsigned long *State;
}AES;
/*
加密數據
byte *input 明文
byte *inSize 明文長
byte *out 密文存放的地方
byte *key 密鑰key
byte *keySize 密鑰長
*/
void Cipher(
unsigned char* input,
int inSize,
unsigned char* out,
unsigned char* key,
int keySize);
/*
解密數據
byte *input 密文
int *inSize 密文長
byte *out 明文存放的地方
byte *key 密鑰key
int *keySize 密鑰長
*/
void InvCipher(
unsigned char* input,
int inSize,
unsigned char* out,
unsigned char* key,
int keySize);
/*
生成加密用的參數AES結構
int inSize 塊大小
byte* 密鑰
int 密鑰長
unsigned long 屬性(標實類型)
返回AES結構指針
*/
AES *InitAES(AES *aes,
int inSize,
unsigned char* key,
int keySize, TYPE type);
/*
生成加密用的參數AES結構
int inSize 塊大小
byte* 密鑰
int 密鑰長
返回AES結構指針
*/
AES *InitAES(
int inSize,
unsigned char* key,
int keySize, BOOL );
/*
加密時進行Nr輪運算
AES * aes 運行時參數
*/
void CipherLoop(
AES *aes);
/*
解密時進行Nr輪逆運算
AES * aes 運行時參數
*/
void InvCipherLoop(
AES *aes);
/*
釋放AES結構和State和密鑰庫word
*/
void freeAES(
AES *aes);
//AES.cpp
#include "stdafx.h"
#include
#include
#include "AES.h"
unsigned char* SubWord(unsigned char* word);
unsigned long* keyExpansion(unsigned char* key, int Nk, int Nr,int);
/*
加密數據
byte *input 明文
byte *inSize 明文長
byte *out 密文存放的地方
byte *key 密鑰key
byte *keySize 密鑰長
*/
void Cipher(unsigned char* input, int inSize, unsigned char* out, unsigned char* key, int keySize)
{
AES aes ;
InitAES(&aes,inSize,key,keySize,encrypt);
memcpy(aes.State,input,inSize);
CipherLoop(&aes);
memcpy(out,aes.State,inSize);
}
/*
解密數據
byte *input 密文
int *inSize 密文長
byte *out 明文存放的地方
byte *key 密鑰key
int *keySize 密鑰長
*/
void InvCipher(unsigned char* input, int inSize, unsigned char* out, unsigned char* key, int keySize)
{
AES aes;
InitAES(&aes,inSize,key,keySize,decrypt);
memcpy(aes.State,input,inSize);
InvCipherLoop(&aes);
memcpy(aes.State,out,inSize);
}
/*
生成加密用的參數AES結構
int inSize 塊大小
byte* 密鑰
int 密鑰長
返回AES結構指針
*/
AES *InitAES(AES *aes,int inSize, unsigned char *key, int keySize, TYPE type)
{
int Nb = inSize >>2,
Nk = keySize >>2,
Nr = Nb < Nk ? Nk:Nb+6;
aes->Nb = Nb;
aes->Nk = Nk;
aes->Nr = Nr;
aes->Word = keyExpansion(key,Nb,Nr,Nk);
aes->State = new unsigned long[Nb+3];
if(type)
aes->State += 3;
return aes;
}
/*
生成加密用的參數AES結構
int inSize 塊大小
byte* 密鑰
int 密鑰長
返回AES結構指針
*/
AES *InitAES(int inSize, unsigned char* key, int keySize,unsigned long type)
{
return InitAES(new AES(),inSize,key,keySize,type);
}
/*
*/
void CipherLoop(AES *aes)
{
unsigned char temp[4];
unsigned long *word8 = aes->Word,
*State = aes->State;
int Nb = aes->Nb,
Nr = aes->Nr;
int r;
for (r = 0; r < Nb; ++r)
{
State[r] ^= word8[r];
}
for (int round =1; round {
word8 += Nb;
/*
假設Nb=4;
---------------------
| s0 | s1 | s2 | s3 |
---------------------
| s4 | s5 | s6 | s7 |
---------------------
| s8 | s9 | sa | sb |
---------------------
| sc | sd | se | sf |
---------------------
| | | | |
---------------------
| | | | |
---------------------
| | | | |
---------------------
*/
memcpy(State+Nb,State,12);
/*
Nb=4;
---------------------
| s0 | | | |
---------------------
| s4 | s5 | | |
---------------------
| s8 | s9 | sa | |
---------------------
| sc | sd | se | sf |
---------------------
| | s1 | s2 | s3 |
---------------------
| | | s6 | s7 |
---------------------
| | | | sb |
---------------------
*/
for(r =0; r {
/*
temp = {Sbox[s0],Sbox[s5],Sbox[sa],Sbox[sf]};
*/
temp[0] = Sbox[*((unsigned char*)State)];
temp[1] = Sbox[*((unsigned char*)(State+1)+1)];
temp[2] = Sbox[*((unsigned char*)(State+2)+2)];
temp[3] = Sbox[*((unsigned char*)(State+3)+3)];
*((unsigned char*)State) = Log_02[temp[0]] ^ Log_03[temp[1]] ^ temp[2] ^ temp[3];
*((unsigned char*)State+1) = Log_02[temp[1]] ^ Log_03[temp[2]] ^ temp[3] ^ temp[0];
*((unsigned char*)State+2) = Log_02[temp[2]] ^ Log_03[temp[3]] ^ temp[0] ^ temp[1];
*((unsigned char*)State+3) = Log_02[temp[3]] ^ Log_03[temp[0]] ^ temp[1] ^ temp[2];
*State ^= word8[r];
State++;
}
State -= Nb;
}
memcpy(State+Nb,State,12);
word8 += Nb;
for(r =0; r {
*((unsigned char*)State) = Sbox[*(unsigned char*)State];
*((unsigned char*)State+1) = Sbox[*((unsigned char*)(State+1)+1)];
*((unsigned char*)State+2) = Sbox[*((unsigned char*)(State+2)+2)];
*((unsigned char*)State+3) = Sbox[*((unsigned char*)(State+3)+3)];
*State ^= word8[r];
State++;
}
}
/*
解密時進行Nr輪逆運算
AES * aes 運行時參數
*/
void InvCipherLoop(AES *aes)
{
unsigned long *Word = aes->Word,
*State = aes->State;
int Nb = aes->Nb,
Nr = aes->Nr;
unsigned char temp[4];
int r =0;
Word += Nb*Nr;
for (r = 0; r < Nb; ++r)
{
State[r] ^= Word[r];
}
State -= 3;
for (int round = Nr-1; round > 0; --round)
{
/*
假設Nb=4;
---------------------
| | | | |
---------------------
| | | | |
---------------------
| | | | |
---------------------
| s0 | s1 | s2 | s3 |
---------------------
| s4 | s5 | s6 | s7 |
---------------------
| s8 | s9 | sa | sb |
---------------------
| sc | sd | se | sf |
---------------------
*/
memcpy(State,State+Nb,12);
/*
Nb=4;
---------------------
| | | | s7 |
---------------------
| | | sa | sb |
---------------------
| | sd | se | sf |
---------------------
| s0 | s1 | s2 | s3 |
---------------------
| s4 | s5 | s6 | |
---------------------
| s8 | s9 | | |
---------------------
| sc | | | |
---------------------
*/
Word -= Nb;
State += Nb+2;
for(r = Nb-1; r >= 0; r--)
{
/*
temp = {iSbox[s0],iSbox[sd],iSbox[sa],iSbox[s7]};
*/
temp[0] = iSbox[*(byte*)State];
temp[1] = iSbox[*((byte*)(State-1)+1)];
temp[2] = iSbox[*((byte*)(State-2)+2)];
temp[3] = iSbox[*((byte*)(State-3)+3)];
*(unsigned long*)temp ^= Word[r];
*(unsigned char*)State = Log_0e[temp[0]] ^ Log_0b[temp[1]] ^ Log_0d[temp[2]] ^ Log_09[temp[3]];
*((unsigned char*)State+1) = Log_0e[temp[1]] ^ Log_0b[temp[2]] ^ Log_0d[temp[3]] ^ Log_09[temp[0]];
*((unsigned char*)State+2) = Log_0e[temp[2]] ^ Log_0b[temp[3]] ^ Log_0d[temp[0]] ^ Log_09[temp[1]];
*((unsigned char*)State+3) = Log_0e[temp[3]] ^ Log_0b[temp[0]] ^ Log_0d[temp[1]] ^ Log_09[temp[2]];
State --;
}
State -= 2;
}
Word -= Nb;
memcpy(State,State+Nb,12);
State += Nb+2;
for(r = Nb-1; r >= 0; r--)
{
*(unsigned char*)State = iSbox[*(unsigned char*)State];
*((unsigned char*)State+1) = iSbox[*((unsigned char*)(State-1)+1)];
*((unsigned char*)State+2) = iSbox[*((unsigned char*)(State-2)+2)];
*((unsigned char*)State+3) = iSbox[*((unsigned char*)(State-3)+3)];
*State ^= Word[r];
State --;
}
}
/*
*--------------------------------------------
*|k0|k1|k2|k3|k4|k5|k6|k7|k8|k9|.......|Nk*4|
*--------------------------------------------
*Nr輪密鑰庫
*每個密鑰列長度為Nb
*---------------------
*| k0 | k1 | k2 | k3 |
*---------------------
*| k4 | k5 | k6 | k7 |
*---------------------
*| k8 | k9 | ka | kb |
*---------------------
*| kc | kd | ke | kf |
*---------------------
*/
unsigned long* keyExpansion(byte* key, int Nb, int Nr, int Nk)
{
unsigned long *w =new unsigned long[Nb * (Nr+1)]; // 4 columns of bytes corresponds to a word
memcpy(w,key,Nk<<2);
unsigned long temp;
for (int c = Nk; c < Nb * (Nr+1); ++c)
{
//把上一輪的最後一行放入temp
temp = w[c-1];
//判斷是不是每一輪密鑰的第一行
if (c % Nk == 0)
{
//左旋8位
temp = (temp<<8)|(temp>>24);
//查Sbox表
SubWord((byte*)&temp);
temp ^= Rcon[c/Nk];
}
else if ( Nk > 6 && (c % Nk == 4) )
{
SubWord((byte*)&temp);
}
//w[c-Nk] 為上一輪密鑰的第一行
w[c] = w[c-Nk] ^ temp;
}
return w;
}
unsigned char* SubWord(unsigned char* word)
{
word[0] = Sbox[ word[0] ];
word[1] = Sbox[ word[1] ];
word[2] = Sbox[ word[2] ];
word[3] = Sbox[ word[3] ];
return word;
}
/*
釋放AES結構和State和密鑰庫word
*/
void freeAES(AES *aes)
{
// for(int i=0;iNb;i++)
// {
// printf("%d\n",i);
// free(aes->State[i]);
// free(aes->Word[i]);
// }
// printf("sdffd");
}
⑽ 如何使用aes加密數據
AES是對稱密鑰演算法,在它進行計算時使用的也是分組密碼體制。先對明文分組,然後利用密鑰進行加密迭代。
具體的演算法細節可以看密碼學的書。