uart串口通信实验报告

2024-07-08

uart串口通信实验报告(精选10篇)

uart串口通信实验报告 篇1

双机通信实验

一、实验目的

UART 串行通信接口技术应用

二、实验实现的功能

用两片核心板之间实现串行通信,将按键信息互发到对方数码管显示。

三、系统硬件设计

(1)单片机的最小系统部分

(2)电源部分

(3)人机界面部分

数码管部分

按键部分

(4)串口通信部分

四、系统软件设计

#include #define uchar unsigned char #define uint unsigned int void send();uchar code0[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9的数码管显示

sbit H1=P3^6;sbit H2=P3^7;sbit L1=P0^5;sbit L2=P0^6;sbit L3=P0^7;

uint m=0,i=0,j;uchar temp,prt;/***y延时函数***/ void delay(uint k){ uint i,j;

}

/***键盘扫描***/ char scan_key(){ H1=0;H2=0;

L1=1;L2=1;L3=1;if(L1==0){ delay(5);if(L1==0){ L1=0;H1=1;H2=1;if(H1==0)} //定义局部变量ij

//外层循环 for(i=0;i

{ m=1;return(m);} if(H2==0){ m=4;return(m);} } }

//KEY1键按下

//KEY4键按下

if(L2==0){ delay(5);if(L2==0){ L2=0;H1=1;H2=1;if(H1==0)

{ m=2;return(m);} if(H2==0){ m=5;return(m);} } }

//KEY5键按下 //KEY2键按下

if(L3==0){ delay(5);if(L3==0){ L3=0;H1=1;H2=1;if(H1==0){ m=3;

//KEY3键按下

}

return(m);} if(H2==0){ m=6;return(m);} } } return(0);

// KEY6键按下

/***主函数***/ main(){ P1M1=0x00;P1M0=0xff;

SCON=0x50;//设定串行口工作方式1 TMOD=0x20;//定时器1,自动重载,产生数据传输速率 TH1=0xfd;//数据传输率为9600 TR1=1;//启动定时器1 P0&=0xf0;while(1){

//如果有按键按下 if(scan_key()){ SBUF=scan_key();//发送数据 while(!TI);TI=0;}

if(RI){ RI=0;}

// //

等待数据传送 清除数据传送标志

//是否有数据到来

// 清除数据传送标志

temp=SBUF;

// 将接收到的数据暂存在temp中

P1=code0[temp];// 数据传送到P1口输出 delay(500);} } //延时500ms

五、实验中遇到的问题及解决方法

(1)串行口和定时器的工作方式设定是关键,本次是按需传输的是两位十六进制数,串行口为工作方式1,定时器为8位自动重载;(2)采用P0&=0xf0语句使4个数码管静态点亮;

(3)在发送和接受过程中,用标识位TI和RI来检测发送和接受是否完成;(4)在用电脑和单片机进行串口通信测试时,电脑的传世速率一定要和单片机的传输速率相等,否则显示会出现错误。

指导老师签字:

uart串口通信实验报告 篇2

关键词:UART,HDL,FPGA,SoC,串口通信

1 介绍

半导体技术革命已经发生, 现在多亿个晶体管被集成在一个芯片上称为So C, 以实现全功能的系统。So C提供了巨大的优势, 例如: (1) 改善功能; (2) 降低成本; (3) 增强可靠性; (4) 减少功耗; (5) 减小系统尺寸; (6) 短的上市时间等。

异步是一种常用的So C数据通信, 微型异步的紧凑尺寸现在在IC设计工业是一个旺盛的需求。来自于不同公司的UART, 例如国家半导体公司 (NSC) 的NS16450A和NS16550A, 还有飞利浦公司的SC26C198和SC28L92在市场上都能获得。在设计的电子系统它们被用来作为分立元件。UART芯片的设计已经被应用到科学领域, 它被用作进行实验的平台来解决不同的研究问题。本文中的UART芯片的设计要求具有模块化功能的独立性, 并且利用行业标准的Verilog HDL代码。Verilog利用有效地描述其行为从而缩短了芯片的设计周期。这是技术上独立。如果某一特定的IC制造过程变得过时, 改变技术文档, 合成一个新的设计水平是可能的, 但是要用一样的Verilog语言代码。

本文接下来的部分描述微型-UART的设计, 模拟以及校验。

2 UART的操作理论

异步串行数据转换为并行, 反之亦然。一个CPU通过它的并行接口与UART进行通信, 而其他的外围设备要通过其串行口与UART进行通信。它被命名为异步接收器和发送器是因为在UART协议中, 接收器和发送器用的不是一个时钟信号。也就是说, 时钟信号不能从一个UART发送器到到另一个UART接收器产生, 图1是一个UART的框图。

系统时钟用来产生波特率时钟, 它是16倍的波特率。Xmitter模块并行数据输入转换为串行数据输出, 而接收器模块反之。

在通过UART传送数据时, 一旦波特率确定之后, 发送器和接收器的内部时钟应该设置为一样的频率。

在每个接收的数据包的开始时, 接收器“合成”它的内部时钟到另一个接收器的内部时钟。它允许接收器在位细胞中心采样数据位。数据包由一个起始位 (通常为0) 、可编程的数据位 (通常6到8位) 、一个可选的奇偶校验位以及可编程的停止位 (通常是1位, 但可能是1.5或2位) 组成。停止位必须总是为逻辑1。通过检测发送器从逻辑1到逻辑0的数据线 (数据线逻辑是高的而UART是处于空闲状态) , 接收器来检测起始位。一旦起始位被检测到, 下一个数据位的“中心”可以放心的从24个跳动点的启动位检测。

3 UART的特点

(1) 独立的控制发射器和接收器模块。 (2) 可编程的波特率发生器。 (3) 紧凑尺寸。 (4) 错误起始位检测。 (5) 可编程字长, 一个起始位, 无奇偶校验和一个停止位。

4 UART的设计和仿真

在MAX-PLUS II环境下使用Verilog来设计和仿真UART。所有UART的功能模块都分别被设计和验证然后它们已经集成到一块。

UART的主要模块是 (1) 波特率发生器。 (2) 发送模块。 (3) 接收模块。

4.1 波特率发生器

UART包括一个可编程的波特率发生器。只要PLD技术支持, 它能输入任何时钟频率。波特率发生器的输出频率由如下公式可以算出:

波特率时钟=系统时钟/波特率*16*除数。

通过改变除数的值, 波特率时钟频率可以变为需要值。

4.2 发送模块 (图2)

FSM控制所有模块, 移位寄存器把8位并行输入数据转换为串行输出数据, 位计数器计发送的位的个数, 并且事件计数器计时钟周期的个数。时钟输入等于16倍的波特率, 它由比特率发生器模块产生。

当“start-pulse”信号输入是一个高电平时, 移位寄存器将从输入“data-in”装载8位, 同时FSM跳变到t-start状态, 这时“tmitdata”输出通过一个2/1mux被设置为0 (start-bit) 。FSM在这个状态下等待16个时钟周期然后跳变到t-wait状态。在这个状态中“tmitdat”的输出通过2/1mux与移位寄存器的串行输出相关联。FSFM在这个状态中等待16个时钟周期然后跳变到t-shift状态, 这时移位寄存器移一位, 然后跳变回t-wait状态。在这个状态中, FSM比较发送位的数。如果发送位的数与表述值 (字长) 相等, 然后FSM跳变到tstop状态, 否则它会停留在t-shift状态。在t-stop状态中, “tmit-dat”输出通过2/1mux被设置为1 (停止位) 。

在每个数据包的发送结束, 发送器在输出端“t-done”产生一个高电平脉冲来指示数据包的发送已经成功完成。

4.3 接收模块 (图3)

接收器的所有模块在“复位输入端”有一个有效的低电平后复位, 并且FSM默认r-idle状态, 这时, 只要串行数据输入保持从1到0, 机器就处于空闲状态。一旦起始位被检测到, FSM就跳变到r-mid状态, 这时通过使用事件计数器计8个周期它会走到start-bit的中心。一旦bit-center被发现, 如果s-din依然是低电平, 那么FSM会跳变到r-wait状态, 否则他是一个无效的起始位并且FSFM跳变回ridle状态。在UART数据线中的噪声能产生这样的效果。在r-wait状态中, FSM等待16个时钟周期然后跳变到r-sam状态, 这时s-din信号被采样到移位寄存器后在等待16个时钟周期然后然后比较采样位和字长 (表述字长值) 。如果它们相等, FSM会跳变到r-stop状态, 否则uhi跳变恩到r-sam状态。在r-stop状态中, s-din信号被感应来检测逻辑1然后在等待16个时钟周期后在d-ready输出端产生一个有效的高电平脉冲然后跳变到r-idle状态。

4.4 设计的验证

UART不同模块的仿真结果中, 逻辑信号证明了它是符合设计要求的。它在FPGA芯片中执行此设计被再一次被验证。UART的核心是可配置的。接收器和发送器独立进行操作, 并且每个对于合成器都是可选的。合成报告表明本设计只需要48个引脚。它证明设计尺寸极其紧凑。UART的操作遵循标准串行通信协议。并且对于其他任何一种标准都是兼容的。通过串行数据线与并行数据线, 它能与其他任何一种标准微控制器和外设相连, 并且可建立数据通信。所有这些UART好的特点使它应用于So C是有吸引力。

5 结语

微机串口通信在实验仪器中的运用 篇3

关键词:单片机;串口通信;设计;实验仪器

中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)18-31498-02

The Microcomputer String Mouth Correspondence is Testing Theinstrument——Practice Discussion

ZENG Ling-qi

(Chengdu Railroad Police Station,Chengdu 610081)

Abstract:The elaboration through the miniature computer monolithicintegrated circuit string mouth and the computer string mouthcorrespondence way, realizes the computer to test the instrument thecontrol and the data acquisition method, take the concrete empiricaldatum as the example, the specify monolithic integrated circuit stringmouth correspondence design and the realization process, and make themultianalysis.

Key words:The monolithic integrated circuit;the string mouthcorrespondence;the design;tests the instrument

1 引言

由于其可编程、易扩展、成本低和体积小等优点,单片机早已被广泛应用于工业控制自动化中,越来越多的物理试验仪器中也使用了单片机进行自动控制,例如实现按键控制、数码管和液晶屏幕的显示、数据采集与模/数转换等等,这样大大方便了学生操作试验仪器。不过有些实验,如“光电效应测普郎克常量”、“夫兰克—赫兹实验”、“散热片的温度特性研究”等,需要读取大量的数据并从中找出这些数据间的相互关系,使得学生在上课时要花大量的时间去读数据,而不是进行逻辑推理和分析,如果能够用微机代替人工进行快速精准的数据采集,并通过计算机软件设计进行复杂的数据分析和处理,无疑对物理实验课是非常好的改进。

2 常用MCS-51芯片的结构与最小系统的硬件实现

以ATMEL公司的AT89S52为例进行说明,AT89S52芯片含有8K的 Flash型的内部 ROM 和 256B的内部 RAM ,对于不太复杂的开发场合,无需扩展外部 ROM,而且可在线编程,有利于进行开发调试,具体可参考读芯片的相关资料[1]。其内部结构如图1所示。

图1 单片机内部结构

图中,外部定时元件通常使用晶体振荡器;复位电路通常设计成上电复位形式或者按键复位形式,以便 CPU及其他功能部件都处于一个确定的初始状态,并开始工作;电源一般使用+5V。程序下载到 ROM 中运行。这样一个单片机的最小系统就实现了,可以通过其他引脚的硬件扩展,并进行软件编程就能响应外部中断、实现定时和外部脉冲计数、进行串并口I/O操作等。

图2是单片机的最小系统的硬件电路实现,其中复位采用上电复位方式,时钟电路采用外节晶体震荡器方式。另外,引脚 EA/VPP为低时访问外部ROM,为高时地址 0000H—0FFFH空间访问ROM,地址1000H-FFFFH空间访问外部ROM,因此这里应该按高,这一点往往是容易忽略的地方[2]。

图2 单片机最小硬件系统

3 串口通信的硬件实现

单片机的4个引脚多数都有第二功能,串口就是P3口的第二功能,其中,P3.0 是串口接收引脚,P3.1 是串图 2 单片机最小硬件系统口发送引脚。在一些实时性要求不太高的场合,将单片机的串口做输出扩展,与外围设备进行数据交换和控制也是一种常用的方法,但更常见在与计算机和其他单片机的通信中,而且硬件电路设计简单,易于开发。图3是单片机串口与计算机的 RS-232C 串口进行通信的一种常用电路连接方法[3]。

图3 单片机串口通信接口电路

进行串口收发时,理论上只需要把计算机串口的接收、发送引脚与单片机的接收引脚 (RXD)和发送引脚(TXD)相连接即可,就像单片机之间的串口通信一样,但是考虑到两者的信号电平标准不同,单片机中的信号使用 TTL 电平,即 >=2.4V 表示“ 1 ”, <=s.5V 表示 “0”,而 RS-232C 总线的电平标准是 -12V 表示“ 1 ”和 +12V 表示“ 0 ”。因此两者通信需要一个电平转换电路接口,图 3 中使用 MAX232 芯片实现这一功能,所接的 5 个电容均为0.1 ,具体可参看该芯片的相关资料[4]。也可以使用其它芯片实现电平转换功能,如MC1488和MC1489。

硬件电路设计好后,可以通过一些串口调试软件进行测试,查看是否能够正确的收发信息。在计算机方面有很多现成的应用程序,也可以用 VC++ 或 VB 等开发相应的软件,这里不详细讨论,接下来谈一谈单片机方面的软件开发。

4 串口通信的软件实现

8051系列单片机进行串口通信时,发送数据由 TXD 引脚送出,接收数据由 RXD 引脚输入。有两个缓冲器 SUBF,一个作发送缓冲器,一个作接收缓冲器,软件设计中可以用两种方式获知单片机发送或者接收了信息。一种是查询方式,程序反复查询发送标志和接收标志是否被硬件置位,若置位说明进行了发送和接收。用这种方式的缺点是 CPU 一直等待串口收发而不能及时响应和处理其他事件。另一种是中断方式,开启串口允许中断,每次单片机从串口收到或者发出信息,均会产生中断,转入中断服务程序进行相应的处理。

串口通信中“波特率”这个概念非常重要,所谓“波特率”也就是“比特率”,描述串口通信的速度,每秒发送或接收数据的二进制位数。在计算机与单片机通信时,双方的波特率必须相同,才能保证发送与接收的同步,进而获得完整的信息。

单片机进行串口通信时有 4 种工作方式,均与波特率的设定有关,波特率的计算也有相应的公式。另外不同的工作方式下通过串口进行异步传输的帧格式也不同。串口通信的收和发分别设置了一个中断标志住,若以中断方式进行串口通信,当发生收/发中断时,对应标志位被硬件置 1 ,可在程序中判断发生的串口通信中断是接收还是发送(因为单片机串口接收中断和发送中断只对应了一个中断向量入口地址)。中断标志位需要用户程序复0,通常在中断服务程序中执行。以上各项设置需要访问两个特殊功能寄存器 SCON(电源控制寄存器)和PCON (电源控制寄存器)[5] 。

5 实验仪器的改造

让我们看一下光电效应测普朗克常量这个实验。在图4 中,一定波长的光照射光电管的阴极K ,电子溢出向阳极A运动,在两极间加反向电压阻止电子向阳极运动,当检测到电流表读数为零时所加载的反向电压叫做截止电压队,对于不同的光照频率 ,有US=h/e(?酌-?酌0 ),其中 h为普朗克常量, e为电子电量,?酌0 为金属阴极 K 的红眼频率,只要找出 ?酌和 US 的线性关系,就可以计算 h 的大小。实验对每一种频率的光都需要改变电压采集电流值,描绘光电管图 4 光电效应原理图的伏安特性曲线,该曲线与电压轴的交点就是截止电压 U0 。

实验仪器的硬件原理框图可以参考图 5 的设计,通过按钮设置电压值,然后读取电流值,送显示屏显示并通过串口传递给计算机进一步处理。

参考文献:

[1]Atmel.DATA HANDBOOK AT89552- based 8—bit Microcontroller with 8K Bytes In-System Programmable Flash,2001.

[2]胡汉才.单片机原理及系统设计[J].清华大学出版版社,2002.

[3]吴金成. 8051单片机实践与与应用[J].清华大学出版社,2002.

[4]axim.DATA HANDBOOK,Max232—based +5V–Powered .Multichannel RS-232 Drivers/Recervers,2001.

[5]李华.MCS—5 系列单片机原理及系统设计[J].清华大学出版社,1997.

通信仿真实验报告 篇4

4.所有仿真程序产生的结果都要有手写分析,即要判决仿真结果就是否正确,说明了什么问题,能够得出什么结论,要如何改进等等。

实验一 随机信号的计算机仿真 实验目的:仿真实现各种分布的随机数发生器 实验内容: 1、均匀分布随机数的产生 用线性同余法,编写 Matlab 程序,产生均匀分布的随机数。

   )5000 mod(] 1323 241 [ 1    n x n x

初始种子 x(0)自己选择。

线性同余算法就是使用最为广泛的伪随机数产生器,该算法含有 4 个参数:模数 m(m>0),乘数 a(0≤a< m),增量 c(0≤c

通信仿真实验报告

2、用反函数法,将均匀分布的随机变量变换为具有单边指数分布的随机变量。编写 Matlab 程序,产生指数分布的随机数。计算并比较理论 pdf 与从直方图得到的 pdf。

指数分布随机变量 pdf 定义为: 0),()exp(2)(    x u x x p X ,)(x u 为单位阶跃函数。

先自行设置取样点数,取 a=5;产生均匀分布随机变量,转化为单边指数分布,理论与仿真符合通信仿真实验报告

设计题: 3、用 Matlab 编程分别产生标准正态分布、指定均值方差正态分布、瑞利分布、赖斯分布、中心与非中心χ2 分布的随机数,并画出相应的 pdf。

y1=normpdf(x,0,1);

y2=normpdf(x,4,2);

通信仿真实验报告

瑞丽

p1= ncfpdf(x,5,20,10);非中心 p= fpdf(x,5,20);中心 4、设输入的随机变量序列 X(n)为 N=1000 独立同分布高斯分布的离散时间序列,均值为 0,方差为 1,采样间隔 0、01s。通过某线性时不变滤波器,输出随机变量序列 Y(n)的功率谱密度为: 2)2(11)(ff S Y 

(1)

设计该滤波器

通信仿真实验报告(2)

产生随机变量序列 Y(n)。

X0=0;

%设置产生序列的递推公式的初始值:X(0)N=1000;

%设置序列的长度 rh=0、9;

%设置产生序列的递推公式的系数 X=zeros(1,N);

%定义序列 X w=rand(1,N)-1/2;

%产生序列 w:在(-1/2,1/2)内均匀分布

%计算序列 X 的 N 个样本:X(1),X(2),…,X(N)

X(1)=rh*X0+w(1);

for i=2:N

X(i)=rh*X(i-1)+w(i);

End X(n)的功率谱密度

滤波器的幅度响应

通信仿真实验报告

附件: 实验二 数字基带调制 实验目的:数字通信系统中,基带传输的仿真。

实验内容: 用 MATLAB 编程仿真实现二进制脉冲幅度调制(PAM)数字通信系统的调制过程。要求画出 12bit 随机输入与对应的已调波形输出。

通信仿真实验报告

1.绘出 40bit 随机输入条件下调制波形形成的眼图。

2.用蒙特卡罗仿真方法计算在信道为加性高斯白噪声时,该系统在不同信噪比下的差错概率。

通信仿真实验报告

3.画出该系统的理论误码率(报告中还要写出理论公式),与蒙特卡罗仿真结果比较,就是否一致,分析结果。

设计题 4、设计 FIR 根升余弦滤波器,具体指标如下:

(1)码片速率为 1、28MHz,采样率为 4 倍码片速率(2)滚 降 系 数 0、22, 冲 激 响 应 序 列 长 度

通信仿真实验报告 65

N_T=8;

%冲激响应序列长度为 2*N_T*Fs/Fc+1 R=0、22

%滚降系数 Fc=1、28e+6;Fs=4*Fc;

%抽样率为 4 倍码片速率 Tc=1、0e-6/1、28;

%码片周期 %[Num,Den] = rcosine(Fc,Fs,“sqrt”,R);

Num=rcosfir(R,N_T,4,Tc,“sqrt”);[H,w]=freqz(Num,[1],1000,“whole”);H=(H(1:1:501))“;w=(w(1:1:501))”;Mag=abs(H);db=20*log10((Mag)/max(Mag));pha=angle(H);plot(w/pi,db);grid;

通信仿真实验报告 axis([0 1-60 1]);xlabel(“归一化角频率”);ylabel(“RRC 滤波器幅度响应(dB)”);(1)[H,w]=freqz(B,A,N)(2)[H,w]=freqz(B,A,N,’whole’)

(1)中 B 与 A 分别为离散系统的系统函数分子、分母多项式的系数向量,返回量 H 则包含了离散系统频响在 0~pi 范围内 N 个频率等分点的值(其中N 为正整数),w 则包含了范围内 N 个频率等分点。调用默认的 N 时,其值就是 512。

(2)中调用格式将计算离散系统在0~pi范内的N个频率等分店的频率响应的值。

因此,可以先调用 freqz()函数计算系统的频率响应,然后利用 abs()与angle()函数及 plot()函数,即可绘制出系统在 或 范围内的频响曲线(3)产生一串(-1、1)等概率分布的随机序列,并对该序列进行脉冲成形滤波。

附件: 实验三 数字频带调制 实验目的:对数字信息的频带传输进行仿真。

通信仿真实验报告 实验内容: 1.用 MATLAB 编程仿真实现二进制相位调制(BPSK)数字通信系统的调制过程。要 求 画 出 12bit 随 机 输 入 与 对 应 的 已 调 波 形 输 出。

2.并用蒙特卡罗仿真方法计算在信道为加性高斯白噪声时,该系统在不同信噪比下的差错概率

通信仿真实验报告 3.画出该系统的理论误码率,与蒙特卡罗仿真结果比较,就是否一致,分析结果。

设计题 4.QPSK 调制,解调与检测的 MATLAB 仿真,并用蒙特卡罗方法估计该系统在加性高斯白噪声情况下的差错概率。

(1)

使用范围在(0,1)内的均匀分布随机数发生器,来产生等概率出现的四

通信仿真实验报告 进制符号序列,再将序列映射到对应的信号向量。

s11=-j;s10=-1;s00=j;s01=1;

%定义 QPSK 信号:4 种可能的取值

N=10000;

%设置发送数据符号的个数

%产生待发送的二进制比特数据流:长度为 2N

signal=rand(1,2*N);

qpsk=zeros(1,N);

%定义经过调制后的信号序列

%产生调制后的信号序列 qpsk

for i=1:N

if signal(2*i-1)<0、5

if signal(2*i)<0、5

qpsk(i)=s00;

else qpsk(i)=s01;

end;

else

if signal(2*i)<0、5

qpsk(i)=s10;

else qpsk(i)=s11;

end;

end;

end;

(2)

利用高斯随机数发生器产生均值为 0,方差为 N0/2 的高斯噪声。

NO=(10^(SNR_in_DB/10))sgma=sqrt(N0/2);

n(1)=gngauss(sgma)(3)

设计检测器,用蒙特卡罗方法估计检测器产生的符号误差。

通信仿真实验报告

实验四 通信信道建模仿真 实验目的:无线通信信道的仿真实现 实验内容: 确定信号的 DTFT 谱分析 窗对频率分辨率的影响

1-1

通信仿真实验报告

1-2

1-3

通信仿真实验报告

1-4

2-1

通信仿真实验报告

2-1

2-2

通信仿真实验报告

3-1

通信仿真实验报告

%% Zero padding DFT

v=2;

dft_vn = fftshift(fft(vn,v*N));

figure(3);

stem([-v*N/2:v*N/2-1]/(v*N/2),abs(dft_vn),“、”);

axis([-1 1 0 35]);

title(“DFT spectrum with 64 zeros padded”);

xlabel(“Normalized digital frequency”);

%% Zero padding DFT

通信仿真实验报告 v=4;

dft_vn = fftshift(fft(vn,v*N));

figure(4);

stem([-v*N/2:v*N/2-1]/(v*N/2),abs(dft_vn),“、”);

title(“DFT spectrum with 3*64 zeros padded”);

xlabel(“Normalized digital frequency”);

axis([-1 1 0 35]);

%%

v = 8;

dft_vn = fftshift(fft(vn,v*N));

figure(5);

stem([-v*N/2:v*N/2-1]/(v*N/2),abs(dft_vn),“、”);

title(“DFT spectrum with 7*64 zeros padded”);

xlabel(“Normalized digital frequency”);

axis([-1 1 0 35]);

4-1: 产生并绘制 10 个高斯-马尔科夫序列样本

通信仿真实验报告

4-1: 功率谱、4-2

R=0、5

通信仿真实验报告

4-2

R=0、5 功率谱、5

通信仿真实验报告

实验五 信道衰落的影响与分集接收仿真 单径 A=0° 单路径移动台包络幅度-移动距离

单路径移动台包络相位

单路径移动台归一化频谱

通信仿真实验报告两径幅度

两径相位

两径频谱

通信仿真实验报告两径 R=0、5 幅度

两径 R=0、5 相位

两径 R=0、5 频谱

通信仿真实验报告

3:3-1 30°幅度

3-1 30°相位

3-1 30°频谱

通信仿真实验报告

3-1 45°幅度

3-1 45°相位

3-1 45°频谱

通信仿真实验报告

3-1 90°幅度

3-1 90°相位

3-1 90°频率

通信仿真实验报告

3-1 180°幅度

3-1 180°相位 3-1 180°频谱

通信仿真实验报告

4-1N=124-1N=256

通信仿真实验报告

5-1 幅度分布 N=12

5-1 幅度分布 N=64

5-1 幅度分布 N=256

通信仿真实验报告

6-1 相位分布 N=12

6-1 相位分布 N=64

6-1 相位 N=256

7-17-1 功率分布 N=12

7-1 功率 N=64

通信仿真实验报告

混沌通信实验报告 篇5

1. 了解保密通信的重要性;

2. 掌握掩盖法实现信号保密的基本原理;

3. 掌握高阶超混沌信号产生原理;

4. 掌握DSP或FPGA上具体实现方法。

二、实验原理

掩盖法实现信号保密原理就是将传输信号与伪随机信号相迭加,受到放将接受到的加密信号去除伪随机信号可恢复出原始信号,在通信过程需要保持信号同步,而伪随机信号采用高阶超混沌发生器产生并经过非线性转化获得。

超混沌数学模型采用4阶Matsumoto-Chua-kobayashi模型:

1010xx210.70 x30004001.5x0x11x002g(x1,x3) 0x3100x40

其中g为分段线性函数

0.23(x1x31)x1x31g(x1,x3)0.2(x1x3) 1x1x31

0.23(xx1)xx11313

有四个输出变量可供选择。

非线性变换采用函数如下:

en(t)g(z1,z2)k1z1k2z2

其中k1、k2取整数,为非线性变换参数也是本加密方法的密钥,z1、z2为超混沌电路的任意两个输出变量。经过非线性变换后的en(t)作为混沌掩盖载波,不同于任何一个超混沌电路的输出信号xi,i1,2,3,4,而是它们的非线性变换,两个非线性信号经过非线性变换后,产生了新的频率成分,显然信号复杂度更高了。

三、实验步骤

1.构造有限长度的信号序列(如语音信号),或由图像转化所整数型信号序列;

2.通过4阶Matsumoto-Chua-kobayashi模型产生超混沌序列;

3.将超混沌序列掩盖信号序列并获得加密信号序列,然后通过信道传输出去;

4.接受方受到信号后采用超混沌信号序列去掩盖获得原信号序列;

5.将实现方案采用Matlab或C语言编程并仿真正确;

6.在瑞泰DSP开发箱或周立功EDA开发箱进行实际测试。

四、实验结果及分析

南邮通信技术实验报告实验一 篇6

课程实验报告

题 目: IP网络中的TCP-UDP通信实验

学 院 通达学院 学 生 姓 名 王伟慧 班 级 学 号 10005002 指 导 教 师 王珺 开 课 学 院 通信与信息工程学院 日 期 2013.5

一,实验目的

了解局域网TCP消息通信过程的机制;

1,了解局域网UDP消息通信过程的特点; 2,熟悉最简单的Socket类的操作和使用;

3,实现字符串通信、文件(ASCII文件)传输、Socket局域网电话的实现;

二 实验设备及软件环境

答:一台或两台装有VC++的带有网卡的PC机(或工控机)。

以太网TCP通信UDP通信服务器端10.10.9.1客户端10.10.9.210.10.9.3710.10.9.15

三 实验步骤

内容一:基于TCP协议的Socket消息发送和接收

说明:事例程序包括“TCP聊天服务器” 与“TCP聊天客户端”。1,运行示例程序“TCP聊天服务器”设置端口号:1001,2,点击“服务器开启服务”

3,运行示例程序“TCP聊天客户端”,设置端口号一定要与“TCP聊天服务器”设置的一致。如果在同一台机器上运行,输入服务器IP地址:127.0.0.1,如果不在同一台机器上,输入局域网上服务器所在机器的IP地址(当然首先确保局域网通畅)4,点击“连接”

在客户端输入文字消息,可以看到服务器端能显示出客户机的名称、IP地址、以及通过Socket消息发送过来的文字内容。内容二,基于UDP的SOCKET消息 1,(必须是在两台机器上,说明书上示意为10.10.9.37和10.10.9.15两个IP地址)均运行程序“UDP客户端”,运行界面如图1.5,注意此时已经没有明确的“服务器”“客户端”之说,“服务器名”输入对端IP地址,端口号必须一致。2,分别点击“打开端口”,连接上服务器后,可以互发消息

四.实验内容及实验结果

TCP通信

UDP通信

五.实验体会

实验过程中,虽然有很多的困难,但经过老师和同学的知道,最终都顺利解决了,实验之后,对TCP、UDP的通信连接有了更加深刻的认识,增长了有关通信技术方面的知识,对以后的学习生活,都会有很大的帮助。

六.思考题

3,如果现在要传送一个TXT文本,应如何实现,写出编程思路?(1)打开文本 将内容读入 缓冲区(2)与 另一台机器建立 socket连接(3)发送

(4)另一台机器 保存接收到的内容

5,TCP本机通信时可以使用哪些IP地址来进行访问? 答:1.本机设定的IP 2.环回地址,以127.开头的IP地址如127.0.0.1 6.TCP通信时如果服务器一方改变端口号,客户端应做怎样的处理?

移动通信系统实验报告三 篇7

一、实验目的

1、使用DSP原理图实现QPSK调制系统的解调。

2、使用Tkplot等模块观测解调信号的波形及其眼图和星座图。

3、观测系统误码率与信噪比的关系曲线图。

二、本次实验所需器件

a.射频信号分离器:Timed Linear---Splitter RF.(用于将信号分为两路信号)b.QPSK解调器: Timed Modem---QPSK_Demod.c.误码率测量模块: Sinks---berIS.d.参数扫描:Controllers---ParamSweep.(用来扫描不同信噪比下的误码率)e.时间延迟模块:Timed Linear---DelayRF.f.噪声:Timed Sources---N_Tones/Noise.g.波形观察模块:Sinks---TimedSink.(用于在DDS下观察信号的波形)

三、实验内容

建立一个完整的QPSK调制解调系统,观察解调后信号的波形,星座图,眼图,测量系统在不同信噪比下的误码率。然后在加噪声和多径的条件下,观察噪声和多径对解调信号的影响(包括星座图,眼图,误码率)。

四、实验结果分析

上图是QPSK系统调制解调的一些实验结果图,S2为调制信号的频谱图(载波为70MHz,主瓣宽度大约50KHz); S4为解调信号的频谱图; T8为基波信号时域波形; T4为解调信号时域波形;

b1为接收信号中信噪比参数变化是解调信号的误码率。

从S4可以看出解调后的信号的频响范围基本在24.3KHz以下。符合滤波后的基波信号频率范围。

对比T4与T8,我们可以发现解调出来的信号基本与之前几波信号一致(一定时延),能够保持信息传递。

从b1我们可以看到当接收到的信号信噪比越大,其系统的误码率也就越低。所以在设计系统是应尽量提高其信噪比。

此图验证的是噪声对信号的干扰,对比此图中的T4与上一图的T4,可以看到加了噪声的解调信号质量比没有加噪声的好。设计时应减少噪声对信号的影响。

计算机网络与通信实验报告 篇8

实验名称 LAN内的资源共享与简单访问控制

一、实验目的

1、通过在网络邻居中进行资源共享,进行开放、禁止、有权限的访问等实验/

2、取消共享的方法等,以实现可控下的访问。

2、可以采用C/S、B/S、peer to peer三种结构进行实验。

二、实验内容

1、增加或删除协议,然后通过网络邻居观察协议对网络连接的影响;

2、进行网络资源的共享实验,分权限设置共享,并进行共享文件的不同操作

三、实验环境 Windows 8操作系统

四、实验记录

1、网络硬件的安装设置(实验中本步骤省略)1)安装网卡

a)把网卡插入计算机的总线插槽,并用螺丝固定好;

b)若非即插即用网卡,则手工设置网卡的IRQ、I/O基址等跳线; c)在Windows中安装网卡驱动程序。2)连接网线

把双绞线的接头的一端插入计算机中的网卡上,另一端插入集线器或交换机的任意一个接口。

2、软件的安装设置

在网上邻居图标上单击右键打开属性窗口。

1)添加网络通讯协议——在配置标签中增加“TCP/IP”协议;

2)设置:IP地址、子网掩码、网关地址、DNS地址等(由于试验中使用的本机采用的是学校的自动获取IP导致的方式,故而此处并没有进行手动设定);

3)设置文件和打印机共享服务——在配置标签中增加“Microsoft 网络上的文件与打印机共享”; 计算机网络与通信实验报告(教师:杜少毅)

4)确认并退出,重新启动系统。

3、资源共享 右击“允许别人访问的目录或驱动器”,选择“共享”,在共享标签中选中“在网络上共享本文件夹”复选框,并在“共享为”后面输入共享名;选中“允许网络用户更改我的文件夹”复选框。计算机网络与通信实验报告(教师:杜少毅)

以上三步做完后,其他用户就可以通过网络邻居访问你的共享资源了。相互之间传送文件及删除文件以验证可以资源共享和权限。

在cmd命令窗口中使用ipconfig命令查看自己的IP地址以便于进行局域网中的文件共享操作: 计算机网络与通信实验报告(教师:杜少毅)

五、实验结论及分析

进行以下改动,再重新观察结果:

1、将上面“

2、软件的安装设置”中“1)添加网络通讯协议”中的协议分别用“NetBIOS”和TCP/IP,各自结果如何?

结果:在禁用了NetBIOS之后,出现了局域网中的其他电脑不能通过IP的方式访问本机的共享文件夹的情况;

分析:经查资料发现,之所以在禁用了NetBIOS之后试验中的局域网中的其他用户不能通过IP的方式访问本机的共享文件夹,是因为试验中使用的这些局域网中的电脑的TCP 445端口(Server MessageBlock,SMB服务)都是关闭的,在开启了TCP 445端口后即使禁用NETBIOS也可以在局域网内实现文件夹共享。

2、将上面“

2、软件的安装设置”中“3)设置文件和打印机共享服务中将“Microsoft 网络上的文件与打印机共享”删除,观察是否还能共享资源。

结果:将“Microsoft 网络上的文件与打印机共享”删除后,不能再实现共享。

3、将上面“

3、资源共享”中“允许网络用户更改我的文件夹”复选框去掉,看看其他用户是否可以删除本机的文件?

结果:将复选框“允许网络用户更改我的文件夹”去掉后,局域网中的其他用户不能再删除本机的文件。

六、实验体会

增加或删除协议NETBIOS,然后通过网络邻居观察协议对网络连接的影响,同时通过查找资料对NETBIOS有了些许了解;通过在网络邻居中进行资源共享,进行开放、禁止、有权限的访问等实验,取消共享的方法等,学会了实现局域网文件共享访问的权限控制。

七、评定成绩 计算机网络与通信实验报告(教师:杜少毅)

实验名称 简单网络协议解析

一、实验目的

1.掌握WireShark软件,通过监测网络流量理解计算机网络体系结构的分层原理。

2.掌握TCP、IP、ETHERNET II协议内容。

二、实验内容

1.安装WireShark软件;

2.通过浏览器访问AME记录,Name是主机别名,Value是主机别名对应的规范主机名,该记录能够向请求主机提供一个主机名对应的规范主机名。

MX记录,Name是邮件服务器别名,Value是邮件服务器别名的规范主机名。通过MX记录,一个公司的邮件服务器和其他服务器可以使用相同的别名 故而,上图的问答是查询主机host。没有权威问答的内容。

2)找到一个有202.117.1.13内容的DNS单元,分析响应过程的分层情况 由图3.3和图3.4可以看到有Authoritative字段,类型为NS,查询到了ip。计算机网络与通信实验报告(教师:杜少毅)

4.通过HTTP协议单元分析TCP、IP、ETHERNET II协议数据单元内容 1)找到一个目的地址为202.117.1.13的HTTP单元,分析请求过程中的TCP、IP、ETHERNET II协议数据单元内容 结合ip数据报的格式可得到各项内容为: Version(版本):4 Header Length(首部长度):20bytes Total Length(总长度):413 Identification标识:0x27d6 Flag标志:0x02 Fragment offset片偏移: 0 Time to live:64 Protocol:TCP(6)……

结合TCP报文格式如可知Source Port源端口:4889 Destination Port 目标端口:80 Sequence Number序列号:1 Acknowledgment number确认号:1 保留:000 Nonce:0 CWR:0 ECN :0 URG:0 ACK:1 PSH:1 …… 计算机网络与通信实验报告(教师:杜少毅)

结合图4.3可知:

目标MAC:杭州Hangzhou_b4:e0:01(38:97:d6:b4:e0:01)源MAC地址:IntelCor_ab:d1:46(因为我的电脑是因特尔酷睿)。……

2)找到一个源地址为202.117.1.13的HTTP单元,分析响应过程中的TCP、IP、ETHERNET II协议数据单元内容

截图已在实验记录中。通过分析数据还可以看到,发过来的数据是一个png图片:

六、实验体会 计算机网络与通信实验报告(教师:杜少毅)

通过本次实验学会如何使用WireShark软件,并通过监测网络流量加深了对计算机网络体系结构的分层原理的理解,在电脑上实际分析了请求过程和响应过程的分层情况,分析了TCP、IP、ETHERNET II协议单元的数据内容,对于课本所学的知识进行了很好的巩固加深了理解。

七、评定成绩

计算机网络与通信实验报告(教师:杜少毅)

实验名称 FTP服务器配置

一、实验目的

掌握如何使用windows 2000 server/XP的IIS配置出ftp服务器

二、实验内容

1、创建一个ftp站点,并且可以实现在别人的计算机上访问该站点;

2、在一个站点下建立多个子站点(使用虚拟目录实现);

3、在同一个套接字(即ip地址+端口)上建立多个站点(使用加主机头名方法实现);

4、对站点进行安全管理(如ntfs文件权限、浏览权限、帐号的使用、ip地址的设定);

5、对用户进行空间的分配,并能上传和下载文件。

三、实验环境

Windows 8

四、实验记录:

搭建方式:windows自带的IIS服务器。实现过程:

1.所需服务的配置:添加windows功能“FTP服务”、“FTP扩展性”和“IIS管理控制台”。计算机网络与通信实验报告(教师:杜少毅)

2.打开IIS管理器添加FTP站点。并按照提示填写信息

填入ip地址,选择“无SSL”,勾选授权”所有用户“允许读、写 计算机网络与通信实验报告(教师:杜少毅)

点击“完成”。

3.在防火墙中允许ftp服务:

4.添加虚拟目录 计算机网络与通信实验报告(教师:杜少毅)

为虚拟目录设置权限(添加用户Authenticated Users): 全下如下图所示: 计算机网络与通信实验报告(教师:杜少毅)

5.登入FTP://115.154.43.246/进入服务器。服务器截图:

可见虚拟目录已经添加: 可以直接访问子站点:

下载文件截图:

上传截图(使用软件leapftp): 计算机网络与通信实验报告(教师:杜少毅)

实验内容:上图所示。

News子目录的添加再添加一个ftp站点如下: 计算机网络与通信实验报告(教师:杜少毅)

可见该站点可以通过ftp.xnow.com(申请到的域名)进行访问。对站点进行安全管理:

在news下设置子站点secret在其属性的安全中设置为访问者不能像其写入数据:

规定访客的浏览权限

5.文件的上传与下载如上图所示。

五、实验结论及分析

在此次试验中所创建一个ftp站点可以实现在别人的计算机上被访问;使用虚拟 计算机网络与通信实验报告(教师:杜少毅)

目录实现在一个站点下建立多个子站点;在同一个套接字(即ip地址+端口)上建立多个站点(使用加主机头名方法实现);对站点进行安全管理(如ntfs文件权限、浏览权限、帐号的使用、ip地址的设定);对用户进行空间的分配,并能成功实现文件的上传和下载。

六、实验体会

由于本次试验中所使用的计算机操作系统为Windows 8,故而在使用使用windows 2000 server/XP的IIS配置ftp服务器时,与所给参考资料由些许出入,因此加大了本次实验的难度,且在实现文件的上传和下载功能时经过多次调试后才得以成功实现。通过本次试验,不仅学会了如何配置ftp服务器,更是提升了个人将理论与实践相结合以及解决问题的能力。

七、评定成绩

计算机网络与通信实验报告(教师:杜少毅)

实验名称 web服务器的搭建

一、实验目的

1.了解Windows 2000 Advanced Server的网络组件,并进行安装和调试; 2.通过实验了解WIN2K中IIS服务器的安装,掌握Web服务器的创建及配置以及访问Web站点。

二、实验内容

配置WIN2K PC成为WEB服务器(IIS 5.0),使用IIS发布WEB站点;在CLIENT PC机(另一台PC机)上使用Internet Explorer访问WEB Server;实现文件的上传和下载。

三、实验环境 Windows8系统

四、实验记录

1.添加所需windows功能:HTTP激活、web管理工具

2.打开IIS管理器添加网站。并按照提示填写信息 计算机网络与通信实验报告(教师:杜少毅)

主要填写ip地址和物理路径。3.启用站点目录。

4.登入web服务器。计算机网络与通信实验报告(教师:杜少毅)

下载文件截图:

上传文件截图: 上图所示

建立多站点,如下图,选择另外一个ip进行站点的添加:

右键已经建立的网站,点击添加虚拟目录: 计算机网络与通信实验报告(教师:杜少毅)

在同一个套接字(即ip地址+端口)上建立多个站点(使用加主机头名方法实现)主机名为申请的域名,DNS解析过程略过

对站点进行安全管理(如ntfs文件权限、浏览权限、帐号的使用、ip地址的设定)

通过cmd命令行将share文件所在的D盘转换成NTFS格式:

五、实验结论及分析

在windows8系统上配置WIN2K PC成为WEB服务器(IIS 5.0)成功,使用IIS发布WEB站点并在CLIENT PC机(另一台PC机)上使用Internet Explorer访问了WEB Server实现了文件的上传和下载。计算机网络与通信实验报告(教师:杜少毅)

六、实验体会

通过本次实验学会如何使用WireShark软件,并通过监测网络流量加深了对计算机网络体系结构的分层原理的理解,在电脑上实际分析了请求过程和响应过程的分层情况,分析了TCP、IP、ETHERNET II协议单元的数据内容,对于课本所学的知识进行了很好的巩固加深了理解。

计算机通信网络实验报告册 篇9

计算机通信网络实验报告册

班级2014通信技术1班

姓名赵自谦

学号201412021949

电气信息工程系电子教研室制

2016年9月

四川工程职业技术学院电气信息工程系

目录

实验一网线制作............................................................................................................................2 实验二对等局域网组建................................................................................................................4 实验三

OUTLOOK配置.............................................................................................................5 实验四常用网络命令..................................................................................................................10 实验五FTP实验...........................................................................................................................15

四川工程职业技术学院电气信息工程系

实验一网线制作

一、实验目的

理解直连线和交叉线的应用范围,掌握直连线和交叉线的制作方法。

二、实验属性

验证性试验。

三、实验仪器设备及器材

RJ45卡线钳一把、水晶头、双绞线、测试仪。

四、实验要求

1、预习报告中需解决以下问题:

(1)掌握不同双绞线的不同用途。(2)掌握不同双绞线的线的排列顺序。

2、试验中正确使用仪器设备,独立操作。

3、试验后按规定要求写出实验报告。

五、实验原理

1、双绞线概述

双绞线由两根具有绝缘保护层的铜导线组成。两根线安按照一定的密度相互绞在一起,就可以改变导线的电气特性,从而降低信号的干扰程度。双绞线电缆比较柔软,便于在墙角等不规则地方施工,但信号的衰减比较大。在大多数应用下,双绞线的最大布线长度为100米。双绞线分为两种类型:非屏蔽双绞线和屏蔽双绞线。

2、双绞线连接

双绞线采用的是RJ-45连接器,俗称水晶头。RJ45水晶头由金属片和塑料构成,特别需要注意的是引脚序号,当金属片面对我们的时候从左至右引脚序号是1-8,这序号做网络联线时非常重要,不能搞错。按照双绞线两端线序的不同,我们一般划分两类双绞线:一类两端线序排列一致,称为直连线;另一类是改变线的排列顺序,称为交叉线。线序如下:

直通线:(机器与集线器连)12345678 A端:橙白,橙,绿白,蓝,蓝白,绿,棕白,棕; B端:橙白,橙,绿白,蓝,蓝白,绿,棕白,棕。交叉线:(机器直连、集线器普通端口级联)12345678 A端:橙白,橙,绿白,蓝,蓝白,绿,棕白,棕;

四川工程职业技术学院电气信息工程系

B端:绿白,绿,橙白,蓝,蓝白,橙,棕白,棕。

在进行设备连接时,我们需要正确的选择线缆。我们将设备的RJ45接口分为MDI和MDIX两类。当同种类型的接口通过双绞线互连时,使用交叉线;当不同类型的接口通过双绞线互连时使用直连线。通常主机和路由器的接口属于MDI,交换机和集线器的接口属于MDIX。例如,路由器和主机相连,采用交叉线;交换机和主机相连则采用直连线。

六、实验步骤

1、剪下一段长度的电缆

2、用压线钳在电缆的一端剥去约2cm护套。

3、分离4对电缆,按照所做双绞线的线序标准(T568A或T568B)排列整齐,并将线弄平直。

4、维持电缆的线序和平整性,用压线钳上的剪刀将线头剪齐,保证不绞合电缆的长度最大为1.2cm。

5、将有序的线头顺着RJ-45头的插口轻轻插入,插到底,并确保护套也被插入。

6、再将RJ-45头塞到压线钳里,用力按下手柄。就这样一个接头就做好了。

7、用同样的方法制做另一个接头。

8、用简单测试仪检查电缆的连通性。

9、注意:如果两个接头的线序都按照T568A或T568B标准制作,则作好的线为直通缆;如果一个接头的线序按照T568A标准制作,而另一个接头的线序按照T568B标准制作,则作好的线为交叉缆。

七、备注说明:

1、伴随着网络技术的迅猛发展,涌现了越来越多的实验软件工具、实验思想、实验方法和技术,相同的网络功能和服务可从不同角度、不同方法去实现。希望同学们能积极查阅国内外的相关文献,跟踪技术发展动态。

2、实验学时较短,远不能满足大学生发现问题、分析问题、解决问题的动手实践能力、工程能力的培养要求,希望同学们在课余能够珍惜时间,积极进行上机、上网操作练习,多动手实践操作,学习、应用所学到的实验方法和技术。

3、在课内外的实验中,提倡同学们在使用本实验指导书中的工具软件和方法的基础上,还可再用其他的工具软件和方法。实验报告可以针对自己收获较大的工具软件和思路、方法来书写。

四川工程职业技术学院电气信息工程系

实验二对等局域网组建

一、实验目的

1.组建两种拓扑结构的局域网。2.能够在局域网内实现资源共享。

二、实验要求

1.用TCP/IP协议配置对等网。采用星型拓扑结构或点到点拓扑结构。2.掌握资源共享的设置和使用方法。

包括:文件夹共享(学生自做)、打印机共享(教师演示)、共享文件夹的映射(学生自做)

四、实验原理

对于一二十台计算机组成的小型局域网环境,当采用对等工作方式时,局域网中所有的工作站均装有相同的协议栈每台汁算机的“地位”是对等的,故称为对等网。

微软最初提供的小型网络解决方案是用简单通信协议NetBEUI来实现。使用该协议的网络,以“工作组”的形式划分子网(计算机的归属),以“计算机名”区分和识别计算机。工作组中的每台计算机既是Client又是Server。后来,Internet风靡全球。微软即在Windows系统中引入TCP/IP,并作为默认的通信协议。单独使用NetBEUI或TCP/IP,均可实现对等网。本实验采用TCP/IP协议。

五、实验条件

1.运行Windows 98或其以上版本的计算机两台以上,计算机上必须配备网 卡及其驱动程序。

2.集线器以及连接线(用实验一制作的网线)

六、实验步骤 第一部分:点到点拓扑结构的对等网组建以及文件夹共享配置(学生每两人一组)

1. 用交叉电缆线将两台电脑相连,观察网卡的指示灯,看每台计算机是否都是处于连通状态。

2.查看网络组件是否完整(是否安装了TCP/IP协议、网卡驱动程序)开启“控制面板”一“网络”图标,查看网络组件是否都在。若无TCP/IP通信协议或缺其他组件,则添加之。

3.配置IP地址

打开“控制面板”中的“网络连接”对话框,打开“本地连接”,选择“TCP/IP协议”,单击“属性”。在出现的“TCP/IP属性”对话框中单击“IP地址”,然后选择“使用下面的地址”,进行相应的配置。同组IP地址一个为10.1.20.2另一个为10.1.20.3,子网掩码都为255.255.255.0,其它不设。单击“确定”按钮。

4.在命令提示符下键入“ipconfig”,由此查看本机的ip地址。

5.给同一实验分组的主机配置相同的“工作组”名和不同的“计算机名”。6.测试网络的连通性。从“网上邻居”看到相邻主机的名字。7.在命令提示符下“Ping + 本组计算机”可以连通。

8.实现文件夹的共享。单击文件夹的属性,把此文件夹设置为共享,则在其

四川工程职业技术学院电气信息工程系

它主机上能够看到此文件夹,实现共享。

9.实现共享文件夹的映射。从网上邻居中找到另一台计算机所共享的文件夹,右击文件夹,找到映射到网络驱动器,单击,即可实现映射。

第二部分:星型拓扑结构的对等网的组建以及打印机的共享实现(学生每批分为二组,共搭建两个网络,每组网段地址指定为10.1.1.0、10.1.2.0,)

1.把每组所有的计算机用直通电缆连接到集线器上,具体做法是每根电联线的1端连接集线器的一个端口,另一端与计算机的网络接口卡相联。

2.观察该集线器的端口和计算机的网络接口卡上的指示灯,这些灯都应该变亮。在有些设备上,指示灯将会闪烁,这是正常现象。

3.配置IP地址

打开“控制面板”中的“网络连接”对话框,打开“本地连接”,选择“TCP/IP协议”,单击“属性”。在出现的“TCP/IP属性”对话框中单击“IP地址”,然后选择“使用下面的地址”,进行相应的配置。

一组IP地址设定为10.1.1.2~10.1.1.9,八台机子每台一个号码,从号码段中任选一个号码。另一个组IP地址设定为10.1.2.2~10.21.2.9,八台计子每台一个号码,子网掩码都为255.255.255.0,其它不设。单击“确定”按钮。

4.重复第一部分的4~7步,测试网络的联通性。

5.实现打印机共享(教师演示)。在连接打印机的计算机上(假设主机名为zhao),从“控制面板”的“打印机”中,右击该打印机名后单击“共享”,在出现的界面中选中“共享为”,输入共享名“work-net”。在其他打印机上,双击“添加打印机”图标,选择“网络打印机”选项,输入打印机的路径及其共享名zhaowork-net。此时从本网络中任何一台打印机上都可实现打印

实验三OUTLOOK配置

一:实验目的及要求

1:掌握个人免费电子邮件格式、优点以及邮箱的申请,邮件的撰写、附件的使用、邮件的发送、接收与回复等;

2:了解企业邮箱在电子商务中的作用

3:掌握邮件软件outlook Express的配置,垃圾邮件的预防、通讯薄等的使用;

二:背景知识

1:电子邮件(Electronic Mail,简称E-mail,又昵称为“伊妹儿”)定义:是一种用户或用户组之间通过计算机网络收发信息的服务,也是我们大众交流信息的常用手段之一。根据第七次中国互联网信息中心权威发布的调查数据显示:电子邮箱、搜索引擎、新闻浏览排在网民最常使用的服务前三位。其中电子邮箱算是互联网最早、最常用的元老级别应用服务。

2:电子邮件类型:根据电子邮箱使用者及邮箱自主域名的不同,可以将邮箱又分为个人邮箱和企业邮箱两个类别。前者的大多数用户还是应用免费的电子邮箱服务,而企业邮箱这种收费的服务模式已经成为中小企业信息化建设过程中一项不可或缺的支出,同时也是各大企业邮箱服务商竞争点,数据显示:2009年全球企业邮件市场收入达到了30亿美元。国外企业油箱的普及率达到60%以

四川工程职业技术学院电气信息工程系

上,而国内仅有5-8%,所以邮件市场是一块诱人的大蛋糕。

3:电子邮件地址:个人邮箱地址典型格式是由三部分组成:用户名@用户所连接的收取Email的服务器地址),整个E-mail地址可理解为网络中某台主机上的某个用户的地址。新浪用户名规则:4-16个字符(包括4、16)或2-8个汉字,请用英文小写、汉字、数字、下划线,不能全部是数字,下划线不能在末尾。126用户名规则:

1.只能由英文字母a~z(不区分大小写)、数字0~

9、下划线组成。2.用户名的起始字符必须是英文字母。如:netease_2005 3.用户名长度为5~20个字符。

企业邮箱是一种为企业用户开发的邮箱,它能使企业使用自己的域名作为邮箱的后缀,用较小的代价获取自己的邮箱服务器。如果企业的域名是,邮箱空间有3.5G,20兆的附件容量。例如:网易126的邮箱(http://):你的邮箱地址是:用户名@sina.com,邮箱空间有2G,单封邮件附件容量为15M。

B:采用SMTP服务器来发送邮件,并采用POP服务器来接受邮件。

这种方法需要通过专门的电子邮件软件才能收发邮件,最典型的微软的OE(Outlook Express),也可以采用国产软件Foxmail.SMTP代表Simple Mail Transfer Protocol(简单邮件传输协议)。SMTP是一组规则,用于由源地址至目的地址传送电子邮件。每一个想接收电子邮件的主机都安装了SMTP服务器。当主机由用户接收了电子邮件并想传递到另外一台服务器,则它联络SMTP服务器。SMTP服务器会作出反应,显示确认、错误消息或特定的请求信息。

POP3代表Post Office Protocol。POP服务器是接收邮件服务器。POP为一种协议,用于处理由客户邮件程序获取邮件的请求。

使用POP服务器接收的消息与使用SMTP服务器发送消息都很简单而且可靠。三:实验过程

(一):申请个人免费邮箱

1:双击打开浏览器IE(Internet Explorer 的简称),输入网址http://。Ping 127.0.0.1

Ping 10.127.116.1

Pingwww.Scetc.net –t

四川工程职业技术学院电气信息工程系

(2)Ipconfig 作用:该诊断命令显示所有当前的TCP/IP网络配置值。该命令在运行DHCP系统上的特殊用途,允许用户决定DHCP配置的TCP/IP配置值。格式:ipconfig[/?|/all|/release[adapter]|/renew[adapter] |/flushdns|/registerdns |/showclassidadapter |/setclassidadapter[classidtoset]] 参数:/all产生完整显示。在没有该开关的情况下ipconfig只显示IP地址、子网掩码和每个网卡的默认网关值。

(3)ARP 作用:显示和修改IP地址与物理地址之间的转换表。格式:ARP-sinet_addreth_addr[if_addr] ARP-a10.172.116.1 参数:

四川工程职业技术学院电气信息工程系

-a显示当前的ARP信息,可以指定网络地址。-g跟-a一样。

(4)Netstat 作用:显示协议统计和当前的TCP/IP网络连接。该命令只有在安装了TCP/IP协议后才可以使用。

格式:Netstat[-a][-e][-n][-s][-pprotocol][-r][interval] 参数:

-a显示所有连接和侦听端口。服务器连接通常不显示。

四川工程职业技术学院电气信息工程系

(5)tracert

四川工程职业技术学院电气信息工程系

实验五FTP实验 一.实验目的: 了解Ftp站点的设置过程。掌握Ftp站点的基本属性配置。掌握Ftp服务器站点权限的设置方法。二.实验要求:(1).能利用Serv-U组建Ftp服务器(2).能对Ftp服务器进行权限、用户等设置(3).能对Ftp服务器进行远程管理等设置 三.实验内容:(1).利用Serv-u建立ftp服务器(2).设置用户权限(3).设置不同文件夹权限

四.实验环境:Windows server 2003及serv-U 软件

五.实验内容:

(1)建立ftp服务器

四川工程职业技术学院电气信息工程系

(2)连接本地服务器,如服务器不能再线,可选择输入密钥,密钥在SERV-U文件夹中“!)注册.txt”中。输入后即可以是服务器正在运行如下图:

(3)服务器连接成功后,右击“域”选择“新建域” 会出现下图界

四川工程职业技术学院电气信息工程系

面,只要在输入本机的IP地址点击下一步即可

四川工程职业技术学院电气信息工程系

域创建完成:

四川工程职业技术学院电气信息工程系

(4)建立用户在新建的域下边右击用户选择新建用户

四川工程职业技术学院电气信息工程系

用户创建完成:

四川工程职业技术学院电气信息工程系

(5)建立一个anonymous(匿名)用户:

anonymous(匿名)用户创建完成:

四川工程职业技术学院电气信息工程系

(6)为以上建立的两个用户设置其登录权限首先选择要设置权限的用户点击目录访问,在文件下面选择你要给该用户的权限即可

选择完成后点击应用

四川工程职业技术学院电气信息工程系

(7)为用户设置IP的访问在编辑规则中选择你要设置的你要设置的是拒绝的IP还是允许的IP 然后在规则中输入你要设置的IP即可

(8)可以为ftp做加密传输可以在“设置”中选择ssl证书

四川工程职业技术学院电气信息工程系

(9)验证我们的服务器是否建立成功。在我的电脑中输入你的ftp地址例如:ftp://192.168.137.188

用zhaofang登陆:

四川工程职业技术学院电气信息工程系

新建文件夹:

删除文件夹:

匿名登陆:

四川工程职业技术学院电气信息工程系

新建文件夹:

打开文件:

删除文件夹:

四川工程职业技术学院电气信息工程系

6.实验结果与体会 实验结果:运行成功!

uart串口通信实验报告 篇10

名:选择课题:系:专

业:学

号:指导教师:

本科实验报告

信息与通信安全

C/C++实现加解密算法及其应用(实验一)

信电系 信息与通信工程

****年**月**日

目录

1.实验内容与要求.......................................................................................................................3 2.实验原理....................................................................................................................................3

2.1 AES原理..........................................................................................................................3

2.1.1 AES总体结构.......................................................................................................3 2.1.2 AES详细结构.......................................................................................................4 1.1 2.CMAC原理................................................................................................................7

实验环境...........................................................................................................................9

4. 代码实现...............................................................................................................................9

4.1字节代替变换.................................................................................................................9 4.2 行移位变换..................................................................................................................11 4.3列混淆变换...................................................................................................................14 4.4 轮密钥加......................................................................................................................17 4.5 AES的加密与解密的实现............................................................................................22 4.6 CMAC代码实现............................................................................................................23 5.思考题...................................................................................................................................27 6.心得体会...............................................................................................................................27 附录(完整程序).....................................................................................................................28

1.实验内容与要求

(1).复习AES原理。

(2).用C/C++编写AES算法并调试通过。(3).复习CMAC原理。

(4).在实现AES基础上,用C/C++编写CMAC算法并调试通过。(5).回答下列思考题。

 AES解密算法和AES的逆算法之间有什么不同?  CMAC与HMAC相比,有什么优点?

2.实验原理

2.1 AES原理 2.1.1 AES总体结构

下图展示了AES加密过程的总体结构。明文分组长度为128位即16字节密钥长度可以为16,24或32字节(在本次设计中选择16字节)。

加密和解密算法是输入是一个128位的分组。在FIPS PUB 197中,这个分组被描述为4*4的字节方阵。这个分组被复制到state数组,饼子啊加密或解密的各个阶段被修改。同样,密钥也被描述为字节的方阵,并被扩展为44字的密钥字序列。

密码由N轮组成,其中轮数依赖于密钥长度,16字节密钥是10轮,前N-1轮由4个不同的变换组成:字节代替,行位移,列混淆,轮密钥加。最后一轮包含三个变换,而在第一轮的前面有一个起始的单变换(轮密钥加),可视为第0轮。每一个变换输入一个活多个4*4的矩阵,并输出一个4*4的矩阵,最后一轮输出为密文。同样,密钥扩展函数为N+1轮密钥,它们是互不相同的4*4矩阵。每一个轮密钥作为每轮的轮密钥加变换的一种输入。

2.1.2 AES详细结构

1)

AES算法未使用Feisel结构,而是在每一轮都使用代替和混淆将整个数据分组作为一个单一的矩阵处理。

2)输入的密钥被扩展为44个32位字所组成的数组w[i],每轮由四个不同的字作为该轮的轮密钥。3)由四个不同的阶段组成,包括一个置换和三个代替。字节代替:

用一个S盒完成分组的字节到字节的代替。行位移:

一个简单的置换。列混淆:

利用GF(2^8)上的算术特性的一个代替。轮密钥加:

当前分组和扩展秘钥的一部分进行按位异或。

(一)字节代替变换

如上图,字节代替变换是一个简单的查表操作。AES定义了一个S盒,它由16*16个字节组成的矩阵,包含了8位所能表示的256个数的一个置换。State中 的每个字节按照如下的方式映射为一个新的字节,把改字节的搞4位作为行值,低四位作为列值,以这些行列值作为索引从S盒的对应位置取出元素作为输出。而其逆向操作则是有对应的逆S盒可进行查表。

(二)行移位变换

如上图,其正向行移位变换中,state的第一行保持不变,把state的第二行循环左移一个字节,state的第三行循环左移两个字节,state的第四行循环左移四个字节。例如:

逆向行移位变换将state中的后三行执行相反方向的一位操作即可。

(三)列混淆变换

如上图,列混淆的正向变换是对每列单独进行操作。每列中的每个字节被映射为一个新值,此值由该列中的4个字通过函数变换得到。这个变换可有下面基于state的矩阵乘法表示:

乘积矩阵中的每个元素军事一行和一列中对应元素的乘积之和。这里的乘法和假发都是定义在GF(2^n)上的。状态中单列的列混淆变换可表示为:

其中一个例子如下:

(四)轮密钥加变换

如上图,在轮密钥加变换中,128位的state按位与128位的轮秘钥XOR。该操作可以视为state的一列中的四个字节与轮秘钥的一个字进行列间的操作,例如:

(五)AES密钥扩展

AES密钥扩展算法的输入值是一个4个字,输出值是一个由44个字组成的移位线性数组。

输入密钥字节被复制到扩展密钥数组的前4个字。然后每次用四个字填充扩展密钥数组余下的部分。在扩展数组中,每一个新增的字w[i]的值依赖于w[i-1]和w[i-4]。在4

个情形中,三个使用了异或。对w数组中下标为4的倍数的的元素采用了更复杂的函数来计算:

(1)字循环的功能时使一个字中的四个字节的循环左移一个字节,即将输入字[B0,B1,B2,B3]变成为[B1,B2,B3,B0].(2)字代替利用S盒对输入字中的每个字节进行字节代替。(3)步骤1和步骤2的结果再与轮常量Rcon[j]相异或。

1.1 CMAC原理

基于密码的消息认证码(CMAC)对于AES,3DES适用,它使用三个密钥:一个密钥长为K,用在密文分组链接的每一步,两个长度为n的密钥,其中k是密钥长度,n为密文分组长度。并且两个n位的密钥可以从加密密钥导出,而不是单独提供。首先,当消息长度是分组长度b的n倍时,我们考虑CMAC的运算情况。对AES,b=128,对于3DES,b=64.这个消息被划分为n组,(M1,M2…,Mn)。算法使用了k比特的加密密钥K和n比特的常数K1。对于AES,密钥长度k为128,192和256比特,对于3DES,密钥长度为112或168比特。CMAC按如下方式计算:

C1E(K,M1)C2E(K,[M2C1])C3E(K,[M3C2])...CnE(K,[MNCn1K1])TMSBTlen(Cn)其中:

T——消息认证码,也称为tag Tlen——T的比特长度

MSBs(X)——比特串X最左边的s位

如果消息不是密文分组长度的整数倍,则最后分组的右边(低有效位)填充一个1和若干个0,使得最后的分组长度为b。除了使用一个不同的n比特密钥K2代替K1外,与前面所述一样进行CMAC运算。

两个n比特的密钥由k比特的加密密钥按如下方式导出:

LE(K,0n)K1LxK2LX2(Lx)x其中乘法(·)是在域GF(2^n)内进行,X和X^2是该域的一次和二次多项式。因此X的二元表示为n-2个0,后跟10,X^2的二元表示为n-3个0,后跟100。对于AES,已获批准的分组长度为X^128 +X^7 +X^2 +X+2.。

当消息长度是分组长度的整数倍:

当消息长度不是分组长度的整数倍:

2.实验环境

装有C_Free 的笔记本

4. 代码实现

首先是实现AES的各个子模块,在验证其正确以后,再进行CMAC的认证算法的实现。

4.1字节代替变换

#include

static unsigned char Sbox[256] =

{ //AES的S盒

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 };

static unsigned char InvSbox[256] = { // AES的逆S盒

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 };

//字节代替变换

void Sub_Byte(unsigned char state[4][4]){ int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=Sbox[state[i][j]];

} //逆向字节代替

void Inv_Sub_Byte(unsigned char state[4][4]){ int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=InvSbox[state[i][j]];

}

int main(){ unsigned char state[4][4]={

{0xea,0x04,0x65,0x85},{0x83,0x45,0x5d,0x96},{0x5c,0x33,0x98,0xb0},{0xf0,0x2d,0xad,0xc5}

};int i,j;//正向替换 Sub_Byte(state);

printf(“正向代替结果:n”);for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%x ”,state[i][j]);

printf(“n”);

}

printf(“n”);//反向替换

Inv_Sub_Byte(state);

printf(“反向代替结果:n”);

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%x ”,state[i][j]);

printf(“n”);

}

}

其测试结果如下,可见该功能可实现是正确的。

4.2 行移位变换

#include

//行移位

void Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp;

} //第一行保持不变,第二行左移一位

temp=state[1][0];for(i=0;i<3;i++)state[1][i]=state[1][i+1];state[1][3]=temp;

//第三行左移2位 temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp;

temp=state[2][1];state[2][1]=state[2][3];state[2][3]=temp;

//第四行左移3位

temp=state[3][3];for(i=3;i>0;i--)state[3][i]=state[3][i-1];state[3][0]=temp;

//逆向行移位

void Inv_Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp;

//第一行保持不变,第二行右移一位

temp=state[1][3];for(i=3;i>0;i--)state[1][i]=state[1][i-1];state[1][0]=temp;

//第三行右移二位 temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp;

temp=state[2][1];state[2][1]=state[2][3];state[2][3]=temp;

//第四行右移三位 temp=state[3][0];for(i=0;i<3;i++)state[3][i]=state[3][i+1];state[3][3]=temp;}

int main(){ int i,j;unsigned char state[4][4]={

{0x87,0xf2,0x4d,0x97},{0xec,0x6e,0x4c,0x90},{0x4a,0xc3,0x46,0xe7},{0x8c,0xd8,0x95,0xa6}

};

Row_Shift(state);printf(“正向行移位变换:n”);for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%02x ”,state[i][j]);

printf(“n”);

}

printf(“n”);

Inv_Row_Shift(state);

printf(“反向向行移位变换:n”);

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%02x ”,state[i][j]);

printf(“n”);

} } 测试结果如下

通过比较,可知结果正确,因此该子模块实现。

4.3列混淆变换

#include //乘法处理部分

unsigned char x_time2(unsigned char state)//乘2处理

{

unsigned char temp;

if(state>=0x80)

temp=(state<<1)^0x1b;//判断b7=1?

else

temp=(state<<1);

return temp;}

unsigned char x_time3(unsigned char state)//乘3处理

{

state=state^x_time2(state);

return state;}

unsigned char x_time4(unsigned char state)//乘4处理

{

state=x_time2(x_time2(state));

return state;}

unsigned char x_time8(unsigned char state)//乘8处理14

{

state=x_time2(x_time2(x_time2(state)));

return state;}

unsigned char x_time9(unsigned char state)//乘9处理

{

state=state^x_time8(state);

return state;}

unsigned char x_timeB(unsigned char state)//乘B处理

{

state=state^x_time2(state)^x_time8(state);

return state;}

unsigned char x_timeD(unsigned char state)//乘D处理

{

state=state^x_time4(state)^x_time8(state);

return state;}

unsigned char x_timeE(unsigned char state)//乘E处理

{

state=x_time2(state)^x_time4(state)^x_time8(state);

return state;}

void MixColumns(unsigned char state[4][4]){

int i,j;unsigned char state_1[4][4];

for(i=0;i<4;i++)for(j=0;j<4;j++)

state_1[i][j]=state[i][j];

for(j=0;j<4;j++)

{

state[0][j]=x_time2(state_1[0][j])^x_time3(state_1[1][j])^state_1[2][j]^state_1[3][j];

state[1][j]=state_1[0][j]^x_time2(state_1[1][j])^x_time3(state_1[2][j])^state_1[3][j];

state[2][j]=state_1[0][j]^state_1[1][j]^x_time2(state_1[2][j])^x_time3(state_1[3][j]);

state[3][j]=x_time3(state_1[0][j])^state_1[1][j]^state_1[2][j]^x_time2(state_1[3][j]);} } //逆向列混淆

void Inv_MixColumns(unsigned char state[4][4]){ int i,j;unsigned char state_1[4][4];

for(i=0;i<4;i++)for(j=0;j<4;j++)

state_1[i][j]=state[i][j];

for(j=0;j<4;j++){

state[0][j]=x_timeE(state_1[0][j])^x_timeB(state_1[1][j])^x_timeD(state_1[2][j])^x_time9(state_1[3][j]);

state[1][j]=x_time9(state_1[0][j])^x_timeE(state_1[1][j])^x_timeB(state_1[2][j])^x_timeD(state_1[3][j]);

state[2][j]=x_timeD(state_1[0][j])^x_time9(state_1[1][j])^x_timeE(state_1[2][j])^x_timeB(state_1[3][j]);

state[3][j]=x_timeB(state_1[0][j])^x_timeD(state_1[1][j])^x_time9(state_1[2][j])^x_timeE(state_1[3][j]);} } int main(){ int i,j;unsigned char state[4][4]={

{0x87,0xf2,0x4d,0x97},{0x6e,0x4c,0x90,0xec},{0x46,0xe7,0x4a,0xc3},{0xa6,0x8c,0xd8,0x95}

};

MixColumns(state);

printf(“正向列混淆结果: n”);

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%x ”,state[i][j]);

printf(“n”);

}

printf(“n”);

Inv_MixColumns(state);

printf(“逆向列混淆结果: n”);

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%x ”,state[i][j]);

printf(“n”);

}

} 其测试结果如下:

通过比较,可知结果正确,因此该子模块实现。

4.4 轮密钥加

#include static unsigned char key[16];static unsigned char ex_key[176];static unsigned char round_key[11][16];static unsigned char Sbox[256] =

{ //AES的S盒

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 };

//秘钥扩展

void key_Expansion(unsigned char key[16]){ int i,j,k;

unsigned char temp[4];//用于寄存w[i-1]

unsigned char t;

unsigned char RC[10]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};

unsigned char Rcon[10][4]={{0x01,0x0,0x0,0x0},{0x02,0x0,0x0,0x0},{0x04,0x0,0x0,0x0},{0x08,0x0,0x0,0x0},{0x10,0x0,0x0,0x0},{0x20,0x0,0x0,0x0},{0x40,0x0,0x0,0x0},{0x80,0x0,0x0,0x0},{0x1b,0x0,0x0,0x0},{0x36,0x0,0x0,0x0},};

//轮常量

for(i=0;i<16;i++)//将输入秘钥复制到扩展秘钥数组的前四个字

{

ex_key[i]=key[i];

}

for(i=16;i<176;i+=4)//秘钥扩展

{

for(j=0;j<4;j++)

temp[j]=ex_key[i-4+j];//用于寄存w[i-1]

if(i%16==0)//对于w[i]中下标为的4的倍数要使用函数g来计算

{

//循环左移

t=temp[0];

for(k=0;k<3;k++)

temp[k]=temp[k+1];

temp[3]=t;

//字代替

for(k=0;k<4;k++)

temp[k]=Sbox[temp[k]];

//与轮常量相异或

for(k=0;k<4;k++)

temp[k]=temp[k]^Rcon[i/16-1][k];}

// 得到最后的w[i],w[i]=w[i-1]^w[i-4]

for(k=i;k

ex_key[k]=ex_key[k-16]^temp[k-i];

}

} //第k轮的轮密钥加

void RoundKey(unsigned char state[4][4],int k){ int i,j;

for(i=0;i<16;i++)round_key[k][i]=ex_key[16*k+i];//第k轮的轮密钥生成 for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=state[i][j]^round_key[k][4*j+i];

}

int main(){

unsigned char key[16]={0x0f,0x15,0x71,0xc9,0x47,0xd9,0xe8,0x59,0x0c,0xb7,0xad,0xd6,0xaf,0x7f,0x67,0x98};unsigned char state[4][4]={

{0xb9,0x94,0x57,0x75},{0xe4,0x8e,0x16,0x51},{0x47,0x20,0x9a,0x3f},{0xc5,0xd6,0xf5,0x3b}

};int i,j;

key_Expansion(key);

for(i=0;i<11;i++)

{

for(j=0;j<16;j++)round_key[i][j]=ex_key[16*i+j];//第k轮的轮密钥生成}

for(i=0;i<11;i++)

{

printf(“第%d轮密钥:n”,i);

for(j=0;j<16;j++)

{

printf(“%02x ”,round_key[i][j]);

if((j+1)%4==0)

printf(“n”);

}

printf(“n”);

}

RoundKey(state,1);

printf(“第一轮结束后的state输出:n”);

for(i=0;i<4;i++)

{

for(j=0;j<4;j++)

printf(“%02x ”,state[i][j]);

printf(“n”);

}

return 0;} 扩展密钥数组如下:

经过比对,可知,密钥扩展是正确的。我又选取了第一轮的轮密钥加:

测试结果如下:

经过比对,可知道轮密钥加的结果是正确的。

4.5 AES的加密与解密的实现

(程序请见附录)参照书上给的例子: Plaintext[16]={ 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0xfe.0xdc,0xba,0x98, 0x76,0x54,0x32,0x10 } key[16]={ 0x0f,0x15,0x71,0xc9, 0x47,0xd9,0xe8,0x59, 0x0c,0xb7,0xad,0xd6, 0xaf,0x7f,0x67,0x98 };其理论结果为:

测试结果如下,经过比对可知结果正确。

4.6 CMAC代码实现

//先用k=128的加密秘钥key产生两个n位的秘钥key_1,key_2 void k1_k2(unsigned char key[16],unsigned char key_1[16],unsigned char key_2[16]){ unsigned char L[16];unsigned char zero_n[16]={0x00};int i;Encryption(zero_n,key,L);//即L=E(K,0^n)

//计算k1=L*x,其中多项式为x^128+x^7+x^2+x+1

if(L[0]>=0x80)

//判断最高位是否是1,若是,则需要约化,即左移一位后,再异或1000 0111=0x87

{

for(i=0;i<16;i++)

key_1[i]=L[i]<<1;//左移一位

key_1[15]=key_1[15]^0x87;

} else {

for(i=0;i<16;i++)

key_1[i]=L[i]<<1;}

//产生key_2=L*x^2=key_1*x

if(key_1[0]>=0x80){

for(i=0;i<16;i++)

key_2[i]=key_1[i]<<1;//左移一位

key_2[15]=key_2[15]^0x87;

}

} else {

for(i=0;i<16;i++)

key_2[i]=key_1[i]<<1;}

//对消息不是密文分组的整数倍,要在分组最后右边填充1及若干个0 //*last_text是最后一个不完整分组,length是最后一组的长度,out_text是填充后的输出

void fill(unsigned char *last_text,int length, unsigned char out_text[16]){ int i;

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

if(i

out_text[i]=last_text[i];

else if(i==length)

out_text[i]=0x80;

else

out_text[i]=0x00;

}

}

void AES_CMAC(unsigned char Mass[],unsigned char key[16],int length, unsigned char mac[]){ int i,j,n,last_l;int flag=0;//用于标记密文分组是否完整

unsigned char M_C1[16]={0x00},M_C2[16], M_C_K[16];//用于存放中间数据

unsigned char key_1[16],key_2[16];//分组密钥

unsigned char last[16],Cn[16];

n=(length+15)/16;//用于确定分几组

last_l=length%16;

k1_k2(key,key_1,key_2);

if(last_l==0)

flag=1;//表明是分组长度b=128的整数倍

if(flag==0)

fill(&Mass[16*(n-1)],last_l,last);//对前n-1轮

for(i=0;i

for(j=0;j<16;j++)

M_C2[j]=M_C1[j]^Mass[16*i+j];

Encryption(M_C2,key,M_C1);

}

if(flag==1)

{

for(i=0;i<16;i++)

M_C_K[i]=Mass[16*(n-1)+i]^M_C1[i]^key_1[i];

Encryption(M_C_K,key,Cn);

}

else {

for(i=0;i<16;i++)

M_C_K[i]=last[i]^M_C1[i]^key_2[i];

Encryption(M_C_K,key,Cn);

} for(i=0;i<16;i++)mac[i]=Cn[i];}

int main(){

unsigned char key[16],Mass[64],T[16];

int i,j,length;

printf(“请输入消息(64byte):n”);//输入消息

for(i=0;i<64;i++)

scanf(“%x”,&Mass[i]);

printf(“请输入密钥: n”);//输入密钥

for(i=0;i<16;i++)

scanf(“%x”,&key[i]);

printf(“需要使用的次数repeat=:n”);

scanf(“%d”,&repeat);

for(i=0;i

{

printf(“请输入不同的密文分组长度length:n”);

scanf(“%d”,&length);

printf(“AES-CMAC输出结果: n”);AES_CMAC(Mass,key,length,T);for(i=0;i<16;i++)

printf(“%x ”, T[i]);printf(“n”);} } 测试结果如下:

根据查阅的资料,可知测试结果是正确的。且从上述结果可知,对于不同的分组长度,输出结果相差很大。

5.思考题

1.AES解密算法和AES的逆算法之间有什么不同?

AES解密算法与其逆算法不同点在于解密算法对密文是先进行轮密钥加(对AES-128而言其扩展密钥是w[40,43])然后开始第一轮的逆向求解,而逆算法时对加密算法的求逆,即将第十轮的算法倒推回去,所以这里有区别。这是由AES特定结构所决定的。

2.CMAC与HMAC相比,有什么优点?

CMAC使用分组密码算法,而HMAC使用散列函数。因为HMAC是基于其所应用的hash函数的,若hash函数的结构存在缺陷,则HMAC的安全性就会大大降低。而CMAC的安全性采用的是分组密码算法,其安全性在于密钥的长度。CMAC的长度可以通过Tlen的变化而变化,输出位数更加灵活。

6.心得体会

首先,刚开始由于这方面知识掌握不是很好,在看完书后又查阅了大量资料,包括一些程序。在这样的一个基础上,对整个编程的思路有了一些认识,按照书本上的AES加密顺序,最先做的就是密钥扩展和轮密钥加。这个部分也是难度最大的部分,主要是输入的都是字节大小的,但密钥扩展后要求是以字为单位输出的。刚开始这个方面纠结了很久,最后为了整个程序比较清晰,还是决定全都以字节为单位,经过一定转换来得到相当于字的效果。

在完成密钥扩展且测试正确后,就开始按顺序设计,字节代替,行移位,列混淆。其中3盒和逆S盒是直接从网上下载的,其他的就是按照书上给的公式和流程图来完成,还是比较顺利的。其解密算法和加密算法也是大同小异的,只是在每个函数中修改一下相应的代码即可。在加密和解密算法都写完后,就是写main函数进行测试,刚开始发现结果总是不对,经过较长时间的查错,发现还是错在轮密钥加中数组转置引起的问题。

在AES设计万仇就是设计CMAC。关于这个程序书上涉及的也较少,但算法还是比较简单的,主要涉及产生两个子密钥和对不完整的分组填充。由于书上没有现有的例子可以参考,因此,我是参照其他同学的例子,进行比较,验证结果是正确的。

附录(完整程序)

#include #include #include #include

static unsigned char key[16];//输入秘钥

static unsigned char ex_key[176];//扩展密钥,其中每四个拼成的就是一个字的秘钥数组

//即w[i]=(ex_key[4*i],ex_key[4*i+1],ex_key[4*i+2],ex_key[4*i+3])static unsigned char round_key[11][16];//轮密钥

static unsigned char Sbox[256] =

{ //AES的S盒

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 };

static unsigned char InvSbox[256] = { // AES的逆S盒

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 };

//乘法处理部分

unsigned char x_time2(unsigned char state)//乘2处理

{

unsigned char temp;

if(state>=0x80)

temp=(state<<1)^0x1b;//判断b7=1?

else

temp=(state<<1);

return temp;}

unsigned char x_time3(unsigned char state)//乘3处理

{

state=state^x_time2(state);

return state;}

unsigned char x_time4(unsigned char state)//乘4处理

{

state=x_time2(x_time2(state));

return state;}

unsigned char x_time8(unsigned char state)//乘8处理

{

state=x_time2(x_time2(x_time2(state)));

return state;}

unsigned char x_time9(unsigned char state)//乘9处理

{

state=state^x_time8(state);

return state;}

unsigned char x_timeB(unsigned char state)//乘B处理

{

state=state^x_time2(state)^x_time8(state);

return state;}

unsigned char x_timeD(unsigned char state)//乘D处理

{

state=state^x_time4(state)^x_time8(state);

return state;}

unsigned char x_timeE(unsigned char state)//乘E处理

{

state=x_time2(state)^x_time4(state)^x_time8(state);

return state;}

//秘钥扩展

void key_Expansion(unsigned char key[16]){ int i,j,k;

unsigned char temp[4];//用于寄存w[i-1]

unsigned char t;

unsigned char RC[10]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1b,0x36};

unsigned char Rcon[10][4]={{0x01,0x0,0x0,0x0},{0x02,0x0,0x0,0x0},{0x04,0x0,0x0,0x0},{0x08,0x0,0x0,0x0},{0x10,0x0,0x0,0x0},{0x20,0x0,0x0,0x0},{0x40,0x0,0x0,0x0},{0x80,0x0,0x0,0x0},{0x1b,0x0,0x0,0x0},{0x36,0x0,0x0,0x0}, };

//轮常量

for(i=0;i<16;i++)//将输入秘钥复制到扩展秘钥数组的前四个字

{

ex_key[i]=key[i];

}

for(i=16;i<176;i+=4)//秘钥扩展

{

for(j=0;j<4;j++)

temp[j]=ex_key[i-4+j];//用于寄存w[i-1]

if(i%16==0)//对于w[i]中下标为的4的倍数要使用函数g来计算

{

//循环左移

t=temp[0];

for(k=0;k<3;k++)

temp[k]=temp[k+1];

temp[3]=t;

//字代替

for(k=0;k<4;k++)

temp[k]=Sbox[temp[k]];

//与轮常量相异或

for(k=0;k<4;k++)

temp[k]=temp[k]^Rcon[i/16-1][k];}

// 得到最后的w[i],w[i]=w[i-1]^w[i-4]

for(k=i;k

ex_key[k]=ex_key[k-16]^temp[k-i];

}

}

//第k轮的轮密钥加

void RoundKey(unsigned char state[4][4],int k){ int i,j;

for(i=0;i<16;i++)

round_key[k][i]=ex_key[16*k+i];//第k轮的轮密钥生成 for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=state[i][j]^round_key[k][4*j+i];

}

//字节代替变换

void Sub_Byte(unsigned char state[4][4]){ int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=Sbox[state[i][j]];

}

//行移位

void Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp;

//第一行保持不变,第二行左移一位

temp=state[1][0];for(i=0;i<3;i++)state[1][i]=state[1][i+1];state[1][3]=temp;

//第三行左移二位

temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp;

temp=state[2][1];state[2][1]=state[2][3];state[2][3]=temp;

//第四行左移三位,即右移一位

temp=state[3][3];for(i=3;i>0;i--)state[3][i]=state[3][i-1];

state[3][0]=temp;}

//列混淆变换

void MixColumns(unsigned char state[4][4]){

int i,j;unsigned char state_1[4][4];

for(i=0;i<4;i++)for(j=0;j<4;j++)

state_1[i][j]=state[i][j];

for(j=0;j<4;j++){

state[0][j]=x_time2(state_1[0][j])^x_time3(state_1[1][j])^state_1[2][j]^state_1[3][j];

state[1][j]=state_1[0][j]^x_time2(state_1[1][j])^x_time3(state_1[2][j])^state_1[3][j];

state[2][j]=state_1[0][j]^state_1[1][j]^x_time2(state_1[2][j])^x_time3(state_1[3][j]);

state[3][j]=x_time3(state_1[0][j])^state_1[1][j]^state_1[2][j]^x_time2(state_1[3][j]);} }

//前9轮每轮有4个步骤

void Round_4(unsigned char state[4][4], int k){ Sub_Byte(state);Row_Shift(state);MixColumns(state);RoundKey(state,k);}

//第10轮有3个步骤

void Round_3(unsigned char state[4][4]){ Sub_Byte(state);Row_Shift(state);RoundKey(state,10);}

//加密算法,明文 Plaintext,密文CipherText,密钥 key

void Encryption(unsigned char Plaintext[16], unsigned char key[16], unsigned CipherText[16])

char

{

int i,j;unsigned char state[4][4];

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[j][i]=Plaintext[4*i+j];

key_Expansion(key);//密钥扩展

//初始轮秘钥加

RoundKey(state,0);//1~10轮

for(i=1;i<10;i++)

Round_4(state,i);

Round_3(state);

//产生密文

for(i=0;i<4;i++)

for(j=0;j<4;j++)

CipherText[4*i+j]=state[j][i];

}

/*////////////////////////////解密////////////////////////////////*/

//逆向行移位

void Inv_Row_Shift(unsigned char state[4][4]){ int i;unsigned char temp;

//第一行保持不变,第二行右移一位

temp=state[1][3];for(i=3;i>0;i--)state[1][i]=state[1][i-1];state[1][0]=temp;

//第三行右移2位

temp=state[2][0];state[2][0]=state[2][2];state[2][2]=temp;

temp=state[2][1];state[2][1]=state[2][3];

} state[2][3]=temp;

//第四行右移三位,即左移1位

temp=state[3][0];for(i=0;i<3;i++)state[3][i]=state[3][i+1];state[3][3]=temp;//逆向字节代替

void Inv_Sub_Byte(unsigned char state[4][4]){ int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=InvSbox[state[i][j]];

}

//逆向列混淆

void Inv_MixColumns(unsigned char state[4][4]){ int i,j;unsigned char state_1[4][4];

for(i=0;i<4;i++)for(j=0;j<4;j++)

state_1[i][j]=state[i][j];

for(j=0;j<4;j++){

state[0][j]=x_timeE(state_1[0][j])^x_timeB(state_1[1][j])^x_timeD(state_1[2][j])^x_time9(state_1[3][j]);

state[1][j]=x_time9(state_1[0][j])^x_timeE(state_1[1][j])^x_timeB(state_1[2][j])^x_timeD(state_1[3][j]);

state[2][j]=x_timeD(state_1[0][j])^x_time9(state_1[1][j])^x_timeE(state_1[2][j])^x_timeB(state_1[3][j]);

state[3][j]=x_timeB(state_1[0][j])^x_timeD(state_1[1][j])^x_time9(state_1[2][j])^x_timeE(state_1[3][j]);

} }

//前9轮每轮有4个步骤

void Inv_Round_4(unsigned char state[4][4], int k){

Inv_Row_Shift(state);Inv_Sub_Byte(state);RoundKey(state,k);Inv_MixColumns(state);}

//第10轮有3个步骤

void Inv_Round_3(unsigned char state[4][4]){ Inv_Row_Shift(state);Inv_Sub_Byte(state);RoundKey(state,0);}

//解密算法,明文 Plaintext,密文CipherText,密钥 key

void Dencryption(unsigned char CipherText[16], unsigned char key[16], unsigned char Plaintext[16]){ int i,j;unsigned char state[4][4];

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j]=CipherText[4*j+i];

key_Expansion(key);//密钥扩展

//初始轮密钥加

RoundKey(state,10);

//1~10轮

for(i=9;i>0;i--)

Inv_Round_4(state,i);Inv_Round_3(state);

//产生明文 for(i=0;i<4;i++)

for(j=0;j<4;j++)

Plaintext[4*i+j]=state[j][i];

}

/*/////////////////////////CMAC////////////////////////////*/ //先用k=128的加密秘钥key产生两个n位的秘钥key_1,key_2 void k1_k2(unsigned char key[16],unsigned char key_1[16],unsigned char key_2[16]){ unsigned char L[16];unsigned char zero_n[16]={0x00};int i;Encryption(zero_n,key,L);//即L=E(K,0^n)

//计算k1=L*x,其中多项式为x^128+x^7+x^2+x+1

if(L[0]>=0x80)

//判断最高位是否是1,若是,则需要约化,即左移一位后,再异或1000 0111=0x87

{

for(i=0;i<16;i++)

key_1[i]=L[i]<<1;//左移一位

key_1[15]=key_1[15]^0x87;

} else {

for(i=0;i<16;i++)

key_1[i]=L[i]<<1;}

//产生key_2=L*x^2=key_1*x

if(key_1[0]>=0x80){

for(i=0;i<16;i++)

key_2[i]=key_1[i]<<1;//左移一位

key_2[15]=key_2[15]^0x87;

} else {

for(i=0;i<16;i++)

key_2[i]=key_1[i]<<1;}

}

//对消息不是密文分组的整数倍,要在分组最后右边填充1及若干个0 //*last_text是最后一个不完整分组,length是最后一组的长度,out_text是填充后的输出

void fill(unsigned char *last_text,int length, unsigned char out_text[16]){ int i;

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

if(i

out_text[i]=last_text[i];

else if(i==length)

out_text[i]=0x80;

else

out_text[i]=0x00;

}

}

void AES_CMAC(unsigned char Mass[],unsigned char key[16],int length, unsigned char mac[]){ int i,j,n,last_l;

int flag=0;//用于标记密文分组是否完整

unsigned char M_C1[16]={0x00},M_C2[16], M_C_K[16];//用于存放中间数据 unsigned char key_1[16],key_2[16];//分组密钥 unsigned char last[16],Cn[16];

n=(length+15)/16;//用于确定分几组

last_l=length%16;

k1_k2(key,key_1,key_2);

if(last_l==0)

flag=1;//表明是分组长度b=128的整数倍

if(flag==0)

fill(&Mass[16*(n-1)],last_l,last);//对前n-1轮

for(i=0;i

for(j=0;j<16;j++)

M_C2[j]=M_C1[j]^Mass[16*i+j];

Encryption(M_C2,key,M_C1);

}

if(flag==1)

{

for(i=0;i<16;i++)

M_C_K[i]=Mass[16*(n-1)+i]^M_C1[i]^key_1[i];

Encryption(M_C_K,key,Cn);

}

else {

for(i=0;i<16;i++)

M_C_K[i]=last[i]^M_C1[i]^key_2[i];

Encryption(M_C_K,key,Cn);

} for(i=0;i<16;i++)mac[i]=Cn[i];}

/*///////////////////////////主函数//////////////////////*/ int main(){

unsigned char Plaintext_1[16]={0x00};unsigned char Ciphertext[16]={0x00};unsigned char Plaintext_2[16]={0x00};unsigned char Mass[64],T[16];

int i,j,length,repeat;//输入明文

printf(“请输入需要加密的明文 :n”);

for(i=0;i<16;i++)scanf(“%x”,&Plaintext_1[i]);

//输入密钥

printf(“请输入密钥:n”);for(i=0;i<16;i++)scanf(“%x”,&key[i]);

//加密

Encryption(Plaintext_1,key,Ciphertext);

printf(“加密后的输出密文:n”);

for(i=0;i<16;i++)

printf(“%02x ”,Ciphertext[i]);

printf(“n”);

//解密

Dencryption(Ciphertext,key,Plaintext_2);

printf(“解密后的输出明文:n”);

for(i=0;i<16;i++)

printf(“%02x ”,Plaintext_2[i]);

printf(“n”);

//CMAC

printf(“请输入消息(64byte):n”);//输入消息

for(i=0;i<64;i++)

{

printf(“%02x ”,Mass[i]);

if((i+1)%8==0)

printf(“n”);

}

printf(“需要使用的次数repeat=:n”);

scanf(“%d”,&repeat);

for(j=0;j

{

printf(“请输入不同的密文分组长度length:n”);

scanf(“%d”,&length);

printf(“AES-CMAC输出结果: n”);

AES_CMAC(Mass,key,length,T);

for(i=0;i<16;i++)

printf(“%02x ”, T[i]);

printf(“n”);

}

上一篇:德育活动统计表下一篇:信息安全技术理论总结