當前位置:首頁 » 編程語言 » 漏洞c語言源碼
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

漏洞c語言源碼

發布時間: 2023-08-27 21:02:42

c語言 如下源碼,運行的時候 有些語句直接被跳過,原因何在求詳解,

那是因為你讀入單個字元的方式不對,

純粹的scanf("%c"),或者getchar()都會把你上一次輸入的回車符( )讀入了。

然後你就讀入了一個回車符。

正確的方式是讀入到一個字元串,再取字元串首位。

代碼:

//老師學生信息放在一起並列印出來
#include<stdio.h>
unioncondition
{
intscore[4];//學生4科成績
charsituation[40];//教師工作情況
};
structpersonal
{
intnum;//編號
charname[10];//姓名
charsex;//性別
charkind;//篩選t或s
unionconditionchange;
};
structpersonalinformation[2];//創建兩個個人信息表
voidmain()
{
inti,j;
for(i=0;i<2;i++)
{
printf("Pleaseinputnum:");//編號
scanf("%d",&information[i].num);

charsex[16];
printf("EntertheMortheW:");//性別
scanf("%s",sex);
information[i].sex=sex[0];

printf("Enterthename:");//名字
scanf("%s",information[i].name);

charts[16];
printf("pleasechangetors:");//t或s
scanf("%s",ts);
information[i].kind=ts[0];

if('t'==information[i].kind)//t為教師工作情況
{
printf("Pleaseenterthesituation:");
scanf("%s",information[i].change.situation);
}
else//s為學生成績
{
for(j=0;j<4;j++)
{
printf("pleaseenterno.%dscore:",j);
scanf("%d",&information[i].change.score[j]);
}
}
}
for(i=0;i<2;i++)//列印以下
{
printf("%d ",information[i].num);//編號
printf("%s ",information[i].name);//姓名
printf("%c ",information[i].sex);//性別
if('t'==information[i].kind)
{
printf("%s",information[i].change.situation);//工作情況
}
else
{
for(j=0;j<4;j++)
{
printf("%d",information[i].change.score[j]);//成績
}
}
}
}

運行:

⑵ c語言中,源代碼是什麼東西

就是寫出來的C語言語句組成的結構。

⑶ c語言程序代碼

C語言源代碼,就是依據C語言規則所寫出的程序代碼,常見的存儲文件擴展名為.c文件和.h文件,分別對應C源文件(source file)和C頭文件(header file)。

C語言是一門編程語言,簡單點說,就是由人類書寫按照一定規范書寫的字元,通過一定手段(編譯鏈接)轉換後,可以讓電腦或者其它電子晶元"讀懂",並按照其要求工作的語言。在所有的編程語言中,C語言是相對古老而原始的,同時也是在同類語言中更接近硬體,最為高效的編程語言。

相關內容:

C語言是一門面向過程的計算機編程語言,與C++、C#、Java等面向對象編程語言有所不同。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、僅產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。

C語言描述問題比匯編語言迅速、工作量小、可讀性好、易於調試、修改和移植,而代碼質量與匯編語言相當。C語言一般只比匯編語言代碼生成的目標程序效率低10%-20%。因此,C語言可以編寫系統軟體。

當前階段,在編程領域中,C語言的運用非常之多,它兼顧了高級語言和匯編語言的優點,相較於其它編程語言具有較大優勢。計算機系統設計以及應用程序編寫是C語言應用的兩大領域。同時,C語言的普適較強,在許多計算機操作系統中都能夠得到適用,且效率顯著。

C語言擁有經過了漫長發展歷史的完整的理論體系,在編程語言中具有舉足輕重的地位。

⑷ 計算機二級C語言最後一道編程題漏洞技巧哪位親,知道謝謝啦!

最好不要採取此類違背考試道德的方法。守信用是很重要的。
誠信是金誠信,這關系著一個人的生活、學習、工作……,一個人如果失去了誠信,將在社會上沒有立足之地。
從字面上說,「誠信」就是誠實守信。孔子說:「人而無信,不知其可也」。因而,說到「誠信」與否,很多人都認為是道德方面的問題,只是一個人在社會的安身立命之本。
可是,在市場經濟社會,道德和利益往往是相鄰而居的。不管是一個人還是一個地方,重視道德,講究誠信,往往可以在經濟上得到豐厚的收益。反之,不但會在道德上遭至譴責,受到法律的嚴懲,更難以在經濟上獲得長久的利益。
就誠信的重要性而言,說「誠信是金」應是不為過的。

⑸ 什麼是C語言緩沖區溢出漏洞怎麼利用誰可以提供詳細的資料

緩沖區溢出漏洞入門介紹
文/hokersome
一、引言
不管你是否相信,幾十年來,緩沖區溢出一直引起許多嚴重的安全性問題。甚至毫不誇張的說,當前網路種種安全問題至少有50%源自緩沖區溢出的問題。遠的不說,一個沖擊波病毒已經令人談溢出色變了。而作為一名黑客,了解緩沖區溢出漏洞則是一門必修課。網上關於溢出的漏洞的文章有很多,但是大多太深或者集中在一個主題,不適合初學者做一般性了解。為此,我寫了這篇文章,主要是針對初學者,對緩沖區溢出漏洞進行一般性的介紹。
緩沖區溢出漏洞是之所以這么多,是在於它的產生是如此的簡單。只要C/C++程序員稍微放鬆警惕,他的代碼裡面可能就出現了一個緩沖區溢出漏洞,甚至即使經過仔細檢查的代碼,也會存在緩沖區溢出漏洞。
二、溢出
聽我說了這些廢話,你一定很想知道究竟什麼緩沖區溢出漏洞,溢出究竟是怎麼發生的。好,現在我們來先弄清楚什麼是溢出。以下的我將假設你對C語言編程有一點了解,一點點就夠了,當然,越多越好。
盡管緩沖區溢出也會發生在非C/C++語言上,但考慮到各種語言的運用程度,我們可以在某種程度上說,緩沖區溢出是C/C++的專利。相信我,如果你在一個用VB寫的程序裡面找溢出漏洞,你將會很出名。回到說C/C++,在這兩種使用非常廣泛的語言裡面,並沒有邊界來檢查數組和指針的引用,這樣做的目的是為了提高效率,而不幸的是,這也留下了嚴重的安全問題。先看下面一段簡單的代碼:
#include<stdio.h>
void main()
{
char buf[8];
gets(buf);
}
程序運行的時候,如果你輸入「Hello」,或者「Kitty」,那麼一切正常,但是如果輸入「Today is a good day」,那麼我得通知你,程序發生溢出了。很顯然,buf這個數組只申請到8個位元組的內存空間,而輸入的字元卻超過了這個數目,於是,多餘的字元將會佔領程序中不屬於自己的內存。因為C/C++語言並不檢查邊界,於是,程序將看似正常繼續運行。如果被溢出部分佔領的內存並不重要,或者是一塊沒有使用的內存,那麼,程序將會繼續看似正常的運行到結束。但是,如果溢出部分佔領的正好的是存放了程序重要數據的內存,那麼一切將會不堪設想。
實際上,緩沖區溢出通常有兩種,堆溢出和堆棧溢出。盡管兩者實質都是一樣,但由於利用的方式不同,我將在下面分開介紹。不過在介紹之前,還是來做一些必要的知識預備。
三、知識預備
要理解大多數緩沖區溢出的本質,首先需要理解當程序運行時機器中的內存是如何分配的。在許多系統上,每個進程都有其自己的虛擬地址空間,它們以某種方式映射到實際內存。我們不必關心描述用來將虛擬地址空間映射成基本體系結構的確切機制,而只關心理論上允許定址大塊連續內存的進程。
程序運行時,其內存裡面一般都包含這些部分:1)程序參數和程序環境;2)程序堆棧,它通常在程序執行時增長,一般情況下,它向下朝堆增長。3)堆,它也在程序執行時增長,相反,它向上朝堆棧增長;4)BSS 段,它包含未初始化的全局可用的數據(例如,全局變數); 5)數據段,它包含初始化的全局可用的數據(通常是全局變數);6)文本段,它包含只讀程序代碼。BSS、數據和文本段組成靜態內存:在程序運行之前這些段的大小已經固定。程序運行時雖然可以更改個別變數,但不能將數據分配到這些段中。下面以一個簡單的例子來說明以上的看起來讓人頭暈的東西:
#include<stdio.h>
char buf[3]="abc";
int i;
void main()
{
i=1
return;
}
其中,i屬於BBS段,而buf屬於數據段。兩者都屬於靜態內存,因為他們在程序中雖然可以改變值,但是其分配的內存大小是固定的,如buf的數據大於三個字元,將會覆蓋其他數據。
與靜態內存形成對比,堆和堆棧是動態的,可以在程序運行的時候改變大小。堆的程序員介面因語言而異。在C語言中,堆是經由 malloc() 和其它相關函數來訪問的,而C++中的new運算符則是堆的程序員介面。堆棧則比較特殊,主要是在調用函數時來保存現場,以便函數返回之後能繼續運行。
四、堆溢出
堆溢出的思路很簡單,覆蓋重要的變數以達到自己的目的。而在實際操作的時候,這顯得比較困難,尤其是源代碼不可見的時候。第一,你必須確定哪個變數是重要的變數;第二,你必須找到一個內存地址比目標變數低的溢出點;第三,在特定目的下,你還必須讓在為了覆蓋目標變數而在中途覆蓋了其他變數之後,程序依然能運行下去。下面以一個源代碼看見的程序來舉例演示一次簡單的堆溢出是如何發生的:
#include "malloc.h"
#include "string.h"
#include "stdio.h"
void main()
{

char *large_str = (char *)malloc(sizeof(char)*1024);
char *important = (char *)malloc(sizeof(char)*6);
char *str = (char *)malloc(sizeof(char)*4);
strcpy(important,"abcdef");//給important賦初值

//下面兩行代碼是為了看str和important的地址
printf("%d/n",str);
printf("%d/n",important);
gets(large_str);//輸入一個字元串
strcpy(str, large_str);//代碼本意是將輸入的字元串拷貝到str
printf("%s/n",important);
}
在實際應用中,這樣的代碼當然是不存在的,這只是一個最簡單的實驗程序。現在我們的目標是important這個字元串變成"hacker"。str和important的地址在不同的環境中並不是一定的,我這里是7868032和7868080。很好,important的地址比str大,這就為溢出創造了可能。計算一下可以知道,兩者中間隔了48個位元組,因此在輸入溢出字元串時候,可以先輸入48個任意字元,然後再輸入hakcer回車,哈哈,出來了,important成了"hacker"。

五、堆棧溢出
堆溢出的一個關鍵問題是很難找到所謂的重要變數,而堆棧溢出則不存在這個問題,因為它將覆蓋一個非常重要的東西----函數的返回地址。在進行函數調用的時候,斷點或者說返回地址將保存到堆棧裡面,以便函數結束之後繼續運行。而堆棧溢出的思路就是在函數裡面找到一個溢出點,把堆棧裡面的返回地址覆蓋,替換成一個自己指定的地方,而在那個地方,我們將把一些精心設計了的攻擊代碼。由於攻擊代碼的編寫需要一些匯編知識,這里我將不打算涉及。我們這里的目標是寫出一個通過覆蓋堆棧返回地址而讓程序執行到另一個函數的堆棧溢出演示程序。
因為堆棧是往下增加的,因此,先進入堆棧的地址反而要大,這為在函數中找到溢出點提供了可能。試想,而堆棧是往上增加的,我們將永遠無法在函數裡面找到一個溢出點去覆蓋返回地址。還是先從一個最簡單的例子開始:
void test(int i)
{
char buf[12];
}
void main()
{
test(1);
}
test 函數具有一個局部參數和一個靜態分配的緩沖區。為了查看這兩個變數所在的內存地址(彼此相對的地址),我們將對代碼略作修改:
void test(int i)
{
char buf[12];
printf("&i = %d/n", &i);
printf("&buf[0] = %d/n", buf);
}
void main()
{
test(1);
}
需要說明的是,由於個人習慣的原因,我把地址結果輸出成10進制形式,但願這並不影響文章的敘述。在我這里,產生下列輸出:&i = 6684072 &buf[0] = 6684052。這里我補充一下,當調用一個函數的時候,首先是參數入棧,然後是返回地址。並且,這些數據都是倒著表示的,因為返回地址是4個位元組,所以可以知道,返回地址應該是保存在從6684068到6684071。因為數據是倒著表示的,所以實際上返回地址就是:buf[19]*256*256*256+buf[18]*256*256+buf[17]*256+buf[16]。
我們的目標還沒有達到,下面我們繼續。在上面程序的基礎,修改成:
#include <stdio.h>
void main()
{
void test(int i);
test(1);
}
void test(int i)
{
void come();
char buf[12];//用於發生溢出的數組
int addr[4];
int k=(int)&i-(int)buf;//計算參數到溢出數組之間的距離
int go=(int)&come;
//由於EIP地址是倒著表示的,所以首先把come()函數的地址分離成位元組
addr[0]=(go << 24)>>24;
addr[1]=(go << 16)>>24;
addr[2]=(go << 8)>>24;
addr[3]=go>>24;
//用come()函數的地址覆蓋EIP
for(int j=0;j<4;j++)
{
buf[k-j-1]=addr[3-j];
}
}
void come()
{
printf("Success!");
}
一切搞定!運行之後,"Success!"成功列印出來!不過,由於這個程序破壞了堆棧,所以系統會提示程序遇到問題需要關閉。但這並不要緊,因為至少我們已經邁出了萬里長征的第一步。

⑹ 求C語言編寫的DES加密解密源代碼

從別的地方抄來的
http://hi..com/493168771/blog/item/5816b034ca19fc44251f144c.html

#include "stdio.h"

#include "time.h"

#include "stdlib.h"

#define PLAIN_FILE_OPEN_ERROR -1

#define KEY_FILE_OPEN_ERROR -2

#define CIPHER_FILE_OPEN_ERROR -3

#define OK 1;

typedef char ElemType;

/* 初始置換表IP */

int IP_Table[64] = { 57,49,41,33,25,17,9,1,

59,51,43,35,27,19,11,3,

61,53,45,37,29,21,13,5,

63,55,47,39,31,23,15,7,

56,48,40,32,24,16,8,0,

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6};

/* 逆初始置換表IP^-1 */

int IP_1_Table[64] = {39,7,47,15,55,23,63,31,

38,6,46,14,54,22,62,30,

37,5,45,13,53,21,61,29,

36,4,44,12,52,20,60,28,

35,3,43,11,51,19,59,27,

34,2,42,10,50,18,58,26,

33,1,41,9,49,17,57,25,

32,0,40,8,48,16,56,24};

/* 擴充置換表E */

int E_Table[48] = {31, 0, 1, 2, 3, 4,

3, 4, 5, 6, 7, 8,

7, 8,9,10,11,12,

11,12,13,14,15,16,

15,16,17,18,19,20,

19,20,21,22,23,24,

23,24,25,26,27,28,

27,28,29,30,31, 0};

/* 置換函數P */

int P_Table[32] = {15,6,19,20,28,11,27,16,

0,14,22,25,4,17,30,9,

1,7,23,13,31,26,2,8,

18,12,29,5,21,10,3,24};

/* S盒 */

int S[8][4][16] =/* S1 */

{{{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7},

{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8},

{4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0},

{15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}},

/* S2 */

{{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10},

{3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},

{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15},

{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}},

/* S3 */

{{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8},

{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},

{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7},

{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12}},

/* S4 */

{{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15},

{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},

{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4},

{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}},

/* S5 */

{{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},

{14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6},

{4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},

{11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}},

/* S6 */

{{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},

{10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8},

{9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},

{4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}},

/* S7 */

{{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},

{13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6},

{1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},

{6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}},

/* S8 */

{{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},

{1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2},

{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},

{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11}}};

/* 置換選擇1 */

int PC_1[56] = {56,48,40,32,24,16,8,

0,57,49,41,33,25,17,

9,1,58,50,42,34,26,

18,10,2,59,51,43,35,

62,54,46,38,30,22,14,

6,61,53,45,37,29,21,

13,5,60,52,44,36,28,

20,12,4,27,19,11,3};

/* 置換選擇2 */

int PC_2[48] = {13,16,10,23,0,4,2,27,

14,5,20,9,22,18,11,3,

25,7,15,6,26,19,12,1,

40,51,30,36,46,54,29,39,

50,44,32,46,43,48,38,55,

33,52,45,41,49,35,28,31};

/* 對左移次數的規定 */

int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

int ByteToBit(ElemType ch,ElemType bit[8]);

int BitToByte(ElemType bit[8],ElemType *ch);

int Char8ToBit64(ElemType ch[8],ElemType bit[64]);

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]);

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]);

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]);

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]);

int DES_ROL(ElemType data[56], int time);

int DES_IP_Transform(ElemType data[64]);

int DES_IP_1_Transform(ElemType data[64]);

int DES_E_Transform(ElemType data[48]);

int DES_P_Transform(ElemType data[32]);

int DES_SBOX(ElemType data[48]);

int DES_XOR(ElemType R[48], ElemType L[48],int count);

int DES_Swap(ElemType left[32],ElemType right[32]);

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]);

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], ElemType plainBlock[8]);

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);

/* 位元組轉換成二進制 */

int ByteToBit(ElemType ch, ElemType bit[8]){

int cnt;

for(cnt = 0;cnt < 8; cnt++){

*(bit+cnt) = (ch>>cnt)&1;

}

return 0;

}

/* 二進制轉換成位元組 */

int BitToByte(ElemType bit[8],ElemType *ch){

int cnt;

for(cnt = 0;cnt < 8; cnt++){

*ch |= *(bit + cnt)<<cnt;

}

return 0;

}

/* 將長度為8的字元串轉為二進制位串 */

int Char8ToBit64(ElemType ch[8],ElemType bit[64]){

int cnt;

for(cnt = 0; cnt < 8; cnt++){

ByteToBit(*(ch+cnt),bit+(cnt<<3));

}

return 0;

}

/* 將二進制位串轉為長度為8的字元串 */

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){

int cnt;

memset(ch,0,8);

for(cnt = 0; cnt < 8; cnt++){

BitToByte(bit+(cnt<<3),ch+cnt);

}

return 0;

}

/* 生成子密鑰 */

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){

ElemType temp[56];

int cnt;

DES_PC1_Transform(key,temp);/* PC1置換 */

for(cnt = 0; cnt < 16; cnt++){/* 16輪跌代,產生16個子密鑰 */

DES_ROL(temp,MOVE_TIMES[cnt]);/* 循環左移 */

DES_PC2_Transform(temp,subKeys[cnt]);/* PC2置換,產生子密鑰 */

}

return 0;

}

/* 密鑰置換1 */

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]){

int cnt;

for(cnt = 0; cnt < 56; cnt++){

tempbts[cnt] = key[PC_1[cnt]];

}

return 0;

}

/* 密鑰置換2 */

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]){

int cnt;

for(cnt = 0; cnt < 48; cnt++){

tempbts[cnt] = key[PC_2[cnt]];

}

return 0;

}

/* 循環左移 */

int DES_ROL(ElemType data[56], int time){

ElemType temp[56];

/* 保存將要循環移動到右邊的位 */

memcpy(temp,data,time);

memcpy(temp+time,data+28,time);

/* 前28位移動 */

memcpy(data,data+time,28-time);

memcpy(data+28-time,temp,time);

/* 後28位移動 */

memcpy(data+28,data+28+time,28-time);

memcpy(data+56-time,temp+time,time);

return 0;

}

/* IP置換 */

int DES_IP_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt < 64; cnt++){

temp[cnt] = data[IP_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/* IP逆置換 */

int DES_IP_1_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt < 64; cnt++){

temp[cnt] = data[IP_1_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/* 擴展置換 */

int DES_E_Transform(ElemType data[48]){

int cnt;

ElemType temp[48];

for(cnt = 0; cnt < 48; cnt++){

temp[cnt] = data[E_Table[cnt]];

}

memcpy(data,temp,48);

return 0;

}

/* P置換 */

int DES_P_Transform(ElemType data[32]){

int cnt;

ElemType temp[32];

for(cnt = 0; cnt < 32; cnt++){

temp[cnt] = data[P_Table[cnt]];

}

memcpy(data,temp,32);

return 0;

}

/* 異或 */

int DES_XOR(ElemType R[48], ElemType L[48] ,int count){

int cnt;

for(cnt = 0; cnt < count; cnt++){

R[cnt] ^= L[cnt];

}

return 0;

}

/* S盒置換 */

int DES_SBOX(ElemType data[48]){

int cnt;

int line,row,output;

int cur1,cur2;

for(cnt = 0; cnt < 8; cnt++){

cur1 = cnt*6;

cur2 = cnt<<2;

/* 計算在S盒中的行與列 */

line = (data[cur1]<<1) + data[cur1+5];

row = (data[cur1+1]<<3) + (data[cur1+2]<<2)

+ (data[cur1+3]<<1) + data[cur1+4];

output = S[cnt][line][row];

/* 化為2進制 */

data[cur2] = (output&0X08)>>3;

data[cur2+1] = (output&0X04)>>2;

data[cur2+2] = (output&0X02)>>1;

data[cur2+3] = output&0x01;

}

return 0;

}

/* 交換 */

int DES_Swap(ElemType left[32], ElemType right[32]){

ElemType temp[32];

memcpy(temp,left,32);

memcpy(left,right,32);

memcpy(right,temp,32);

return 0;

}

/* 加密單個分組 */

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]){

ElemType plainBits[64];

ElemType Right[48];

int cnt;

Char8ToBit64(plainBlock,plainBits);

/* 初始置換(IP置換) */

DES_IP_Transform(plainBits);

/* 16輪迭代 */

for(cnt = 0; cnt < 16; cnt++){

memcpy(Right,plainBits+32,32);

/* 將右半部分進行擴展置換,從32位擴展到48位 */

DES_E_Transform(Right);

/* 將右半部分與子密鑰進行異或操作 */

DES_XOR(Right,subKeys[cnt],48);

/* 異或結果進入S盒,輸出32位結果 */

DES_SBOX(Right);

/* P置換 */

DES_P_Transform(Right);

/* 將明文左半部分與右半部分進行異或 */

DES_XOR(plainBits,Right,32);

if(cnt != 15){

/* 最終完成左右部的交換 */

DES_Swap(plainBits,plainBits+32);

}

}

/* 逆初始置換(IP^1置換) */

DES_IP_1_Transform(plainBits);

Bit64ToChar8(plainBits,cipherBlock);

return 0;

}

/* 解密單個分組 */

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48],ElemType plainBlock[8]){

ElemType cipherBits[64];

ElemType Right[48];

int cnt;

Char8ToBit64(cipherBlock,cipherBits);

/* 初始置換(IP置換) */

DES_IP_Transform(cipherBits);

/* 16輪迭代 */

for(cnt = 15; cnt >= 0; cnt--){

memcpy(Right,cipherBits+32,32);

/* 將右半部分進行擴展置換,從32位擴展到48位 */

DES_E_Transform(Right);

/* 將右半部分與子密鑰進行異或操作 */

DES_XOR(Right,subKeys[cnt],48);

/* 異或結果進入S盒,輸出32位結果 */

DES_SBOX(Right);

/* P置換 */

DES_P_Transform(Right);

/* 將明文左半部分與右半部分進行異或 */

DES_XOR(cipherBits,Right,32);

if(cnt != 0){

/* 最終完成左右部的交換 */

DES_Swap(cipherBits,cipherBits+32);

}

}

/* 逆初始置換(IP^1置換) */

DES_IP_1_Transform(cipherBits);

Bit64ToChar8(cipherBits,plainBlock);

return 0;

}

/* 加密文件 */

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile){

FILE *plain,*cipher;

int count;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((plain = fopen(plainFile,"rb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

if((cipher = fopen(cipherFile,"wb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

/* 設置密鑰 */

memcpy(keyBlock,keyStr,8);

/* 將密鑰轉換為二進制流 */

Char8ToBit64(keyBlock,bKey);

/* 生成子密鑰 */

DES_MakeSubKeys(bKey,subKeys);

while(!feof(plain)){

/* 每次讀8個位元組,並返回成功讀取的位元組數 */

if((count = fread(plainBlock,sizeof(char),8,plain)) == 8){

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

}

if(count){

/* 填充 */

memset(plainBlock + count,'\0',7 - count);

/* 最後一個字元保存包括最後一個字元在內的所填充的字元數量 */

plainBlock[7] = 8 - count;

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

fclose(plain);

fclose(cipher);

return OK;

}

/* 解密文件 */

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile){

FILE *plain, *cipher;

int count,times = 0;

long fileLen;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((cipher = fopen(cipherFile,"rb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

if((plain = fopen(plainFile,"wb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

/* 設置密鑰 */

memcpy(keyBlock,keyStr,8);

/* 將密鑰轉換為二進制流 */

Char8ToBit64(keyBlock,bKey);

/* 生成子密鑰 */

DES_MakeSubKeys(bKey,subKeys);

/* 取文件長度 */

fseek(cipher,0,SEEK_END); /* 將文件指針置尾 */

fileLen = ftell(cipher); /* 取文件指針當前位置 */

rewind(cipher); /* 將文件指針重指向文件頭 */

while(1){

/* 密文的位元組數一定是8的整數倍 */

fread(cipherBlock,sizeof(char),8,cipher);

DES_DecryptBlock(cipherBlock,subKeys,plainBlock);

times += 8;

if(times < fileLen){

fwrite(plainBlock,sizeof(char),8,plain);

}

else{

break;

}

}

/* 判斷末尾是否被填充 */

if(plainBlock[7] < 8){

for(count = 8 - plainBlock[7]; count < 7; count++){

if(plainBlock[count] != '\0'){

break;

}

}

}

if(count == 7){/* 有填充 */

fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain);

}

else{/* 無填充 */

fwrite(plainBlock,sizeof(char),8,plain);

}

fclose(plain);

fclose(cipher);

return OK;

}

int main()

{ DES_Encrypt("1.txt","key.txt","2.txt");
system("pause");
DES_Decrypt("2.txt","key.txt","3.txt");

getchar();

return 0;

}