c60编译器下载
❶ VHDL数字时钟完整程序代码(要求要有元件例化,并且有按键消抖),谢谢啦啦啦啦
图11
程序如下:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity xuan21 is
Port ( alarm,a,b: in std_logic;
y:out std_logic);
end xuan21 ;
architecture one of xuan21 is
begin
process(alarm,a,b)
begin
if alarm='0' then y<=a;else y<=b;
end if;
end process;
end one;
仿真波形如下图12:
图12
(2)三位二选一:
模块图如图13。用以进行正常计时时间与闹铃时间显示的选择,alarm输入为按键。当alarm按键未曾按下时二选一选择器会选择输出显示正常的计时结果,否则当alarm按键按下时选择器将选择输出显示闹铃时间显示。
图13
程序如下:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity x213 is
Port ( alarm : in std_logic;
y:out std_logic_vector(3 downto 0);
a,b: in std_logic_vector(3 downto 0));
end x213;
architecture one of x213 is
begin
process(alarm,a,b)
begin
if alarm='0' then y<=a;else y<=b;
end if;
end process;
end one;
仿真结果如下图14:
图14
8、整点报时及闹时:
模块图如图15。在59分51秒、53秒、55秒、57秒给扬声器赋以低音512Hz信号,在59分59秒给扬声器赋以高音1024Hz信号,音响持续1秒钟,在1024Hz音响结束时刻为整点。当系统时间与闹铃时间相同时给扬声器赋以高音1024Hz信号。闹时时间为一分钟。
图15
程序如下:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity voice is
Port ( hou1,huo0,min1,min0,sec1,sec0,hh,hl,mh,ml: std_logic_vector(3 downto 0);
in_1000,in_500:in std_logic;
q : out std_logic);
end voice;
architecture one of voice is
begin
process(min1,min0,sec1,sec0)
begin
if min1="0101" and min0="1001" and sec1="0101" then
if sec0="0001" or sec0="0011" or sec0="0101" or sec0="0111"
then q<=in_500;
elsif sec1="0101" and sec0="1001" then q<=in_1000;
else q<='0';
end if;
else q<='0';
end if;
if min1=mh and min0=ml and hou1=hh and huo0=hl then
q<=in_1000;
end if;
end process;
end one;
仿真波形如下图16
图16
9、顶层原理图:
三、感想
通过这次设计,既复习了以前所学的知识,也进一步加深了对EDA的了解,让我对它有了更加浓厚的兴趣。特别是当每一个子模块编写调试成功时,心里特别的开心。但是在画顶层原理图时,遇到了不少问题,最大的问题就是根本没有把各个模块的VHD文件以及生成的器件都全部放在顶层文件的文件夹内,还有就是程序设计的时候考虑的不够全面,没有联系着各个模式以及实验板的情况来编写程序,以至于多考虑编写了译码电路而浪费了很多时间。在波形仿真时,也遇到了一点困难,想要的结果不能在波形上得到正确的显示
:在分频模块中,设定输入的时钟信号后,却只有二分频的结果,其余三个分频始终没反应。后来,在数十次的调试之后,才发现是因为规定的信号量范围太大且信号的初始值随机,从而不能得到所要的结果。还有的仿真图根本就不出波形,怎么调节都不管用,后来才知道原来是路径不正确,路径中不可以有汉字。真是细节决定成败啊!总的来说,这次设计的数字钟还是比较成功的,有点小小的成就感,终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,使自己对以后的路有了更加清楚的认识,同时,对未来有了更多的信心。
四、参考资料:
1、潘松,王国栋,VHDL实用教程〔M〕.成都:电子科技大学出版社,2000.(1)
2、崔建明主编,电工电子EDA仿真技术北京:高等教育出版社,2004
3、李衍编着,EDA技术入门与提高王行西安:西安电子科技大学出版社,2005
4、侯继红,李向东主编,EDA实用技术教程北京:中国电力出版社,2004
5、沈明山编着,EDA技术及可编程器件应用实训北京:科学出版社,2004
6、侯伯亨等,VHDL硬件描述语言与数字逻辑电路设计西安: 西安电子科技大学出版社,1997
7、辛春艳编着,VHDL硬件描述语言北京:国防工业出版社,2002 就这些
❷ 关于碳60
主要应用于材料科学,超导体等方面。
C60 (碳60简称为C60) 分子C60分子是一种由60个碳原子构成的分子,它形似足球,是一种很稳定的分子,主要应用于材料科学,超导体等方面。金刚石、石墨、C60分子的结构示意图.世人瞩目的足球烯-C60.C60分子是一种由60个碳原子结合形成的稳定分子,它具有60个顶点和32个面,其中12个为正五边形,20个为正六边形,它形似足球,因此又被称为足球烯。足球烯是美国休斯顿赖斯大学的克罗脱(Kroto, H.W.)和史沫莱(Smalley, R.E.)等人于1985年提出的,他们用大功率激光束轰击石墨使其气化,用1MPa压强的氦气产生超声波,使被激光束气化的碳原子通过一个小喷嘴进入真空膨胀,并迅速冷却形成新的碳原子,从而得到了C60。C60的组成及结构已经被质谱,X射线分析等实验证明。此外,还有C70等许多类似C60分子也已被相继发现。1991年,科学家们发现,C60中掺以少量某些金属后具有超导性,且这种材料的制作工艺比制作传统的超导材料——陶瓷要简单,质地又十分坚硬,所以人们预言C60在超导材料领域具有广阔的应用前景。碳60分子俗称布基球,由60个碳原子构成,它们组成一个笼状结构。这一分子于1985年被发现后因它具有特殊性质,一直是化学家们的热门研究对象。
碳-60分子是科学家发现的,它由60个碳原子组成形似足球的分子,因而又被称为“布基球”。在过去的实验中,它表现出与普通形态的碳元素大不相同的物理、化学性质.
❸ 常用数据校验方法有哪些
奇偶校验”。内存中最小的单位是比特,也称为“位”,位有只有两种状态分别以1和0来标示,每8个连续的比特叫做一个字节(byte)。不带奇偶校验的内存每个字节只有8位,如果其某一位存储了错误的值,就会导致其存储的相应数据发生变化,进而导致应用程序发生错误。而奇偶校验就是在每一字节(8位)之外又增加了一位作为错误检测位。在某字节中存储数据之后,在其8个位上存储的数据是固定的,因为位只能有两种状态1或0,假设存储的数据用位标示为1、1、 1、0、0、1、0、1,那么把每个位相加(1+1+1+0+0+1+0+1=5),结果是奇数,那么在校验位定义为1,反之为0。当CPU读取存储的数据时,它会再次把前8位中存储的数据相加,计算结果是否与校验位相一致。从而一定程度上能检测出内存错误,奇偶校验只能检测出错误而无法对其进行修正,同时虽然双位同时发生错误的概率相当低,但奇偶校验却无法检测出双位错误。
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc 发明,由 MD2/MD3/MD4 发展而来的。MD5的实际应用是对一段Message(字节串)产生fingerprint(指纹),可以防止被“篡改”。举个例子,天天安全网提供下载的MD5校验值软件WinMD5.zip,其MD5值是,但你下载该软件后计算MD5 发现其值却是,那说明该ZIP已经被他人修改过,那还用不用该软件那你可自己琢磨着看啦。
MD5广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的,用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,来验证该用户的合法性。
MD5校验值软件WinMD5.zip汉化版,使用极其简单,运行该软件后,把需要计算MD5值的文件用鼠标拖到正在处理的框里边,下面将直接显示其MD5值以及所测试的文件名称,可以保留多个文件测试的MD5值,选定所需要复制的MD5值,用CTRL+C就可以复制到其它地方了。
参考资料:http://..com/question/3933661.html
CRC算法原理及c语言实现 -来自(我爱单片机)
摘 要 本文从理论上推导出CRC算法实现原理,给出三种分别适应不同计算机或微控制器硬件环境的C语言程序。读者更能根据本算法原理,用不同的语言编写出独特风格更加实用的CRC计算程序。
关键词 CRC 算法 C语言
1 引言
循环冗余码CRC检验技术广泛应用于测控及通信领域。CRC计算可以靠专用的硬件来实现,但是对于低成本的微控制器系统,在没有硬件支持下实现CRC检验,关键的问题就是如何通过软件来完成CRC计算,也就是CRC算法的问题。
这里将提供三种算法,它们稍有不同,一种适用于程序空间十分苛刻但CRC计算速度要求不高的微控制器系统,另一种适用于程序空间较大且CRC计算速度要求较高的计算机或微控制器系统,最后一种是适用于程序空间不太大,且CRC计算速度又不可以太慢的微控制器系统。
2 CRC简介
CRC 校验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码)r位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端,则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。
16位的CRC码产生的规则是先将要发送的二进制序列数左移16位(既乘以 )后,再除以一个多项式,最后所得到的余数既是CRC码,如式(2-1)式所示,其中B(X)表示n位的二进制序列数,G(X)为多项式,Q(X)为整数,R(X)是余数(既CRC码)。
(2-1)
求CRC 码所采用模2加减运算法则,既是不带进位和借位的按位加减,这种加减运算实际上就是逻辑上的异或运算,加法和减法等价,乘法和除法运算与普通代数式的乘除法运算是一样,符合同样的规律。生成CRC码的多项式如下,其中CRC-16和CRC-CCITT产生16位的CRC码,而CRC-32则产生的是32位的CRC码。本文不讨论32位的CRC算法,有兴趣的朋友可以根据本文的思路自己去推导计算方法。
CRC-16:(美国二进制同步系统中采用)
CRC-CCITT:(由欧洲CCITT推荐)
CRC-32:
接收方将接收到的二进制序列数(包括信息码和CRC码)除以多项式,如果余数为0,则说明传输中无错误发生,否则说明传输有误,关于其原理这里不再多述。用软件计算CRC码时,接收方可以将接收到的信息码求CRC码,比较结果和接收到的CRC码是否相同。
3 按位计算CRC
对于一个二进制序列数可以表示为式(3-1):
(3-1)
求此二进制序列数的CRC码时,先乘以 后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(3-2)所示:
(3-2)
可以设: (3-3)
其中 为整数, 为16位二进制余数。将式(3-3)代入式(3-2)得:
(3-4)
再设: (3-5)
其中 为整数, 为16位二进制余数,将式(3-5)代入式(3-4),如上类推,最后得到:
(3-6)
根据CRC的定义,很显然,十六位二进制数 既是我们要求的CRC码。
式(3 -5)是编程计算CRC的关键,它说明计算本位后的CRC码等于上一位CRC码乘以2后除以多项式,所得的余数再加上本位值除以多项式所得的余数。由此不难理解下面求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,0x1021与多项式有关。
[code]
unsigned int cal_crc(unsigned char *ptr, unsigned char len) {
unsigned char i;
unsigned int crc=0;
while(len--!=0) {
for(i=0x80; i!=0; i/=2) {
if((crc&0x8000)!=0) {crc*=2; crc^=0x1021;} /* 余式CRC乘以2再求CRC */
else crc*=2;
if((*ptr&i)!=0) crc^=0x1021; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
[code]
按位计算CRC虽然代码简单,所占用的内存比较少,但其最大的缺点就是一位一位地计算会占用很多的处理器处理时间,尤其在高速通讯的场合,这个缺点更是不可容忍。因此下面再介绍一种按字节查表快速计算CRC的方法。
4 按字节计算CRC
不难理解,对于一个二进制序列数可以按字节表示为式(4-1),其中 为一个字节(共8位)。
(4-1)
求此二进制序列数的CRC码时,先乘以 后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(4-2)所示:
(4-2)
可以设: (4-3)
其中 为整数, 为16位二进制余数。将式(4-3)代入式(4-2)得:
(4-4)
因为:
(4-5)
其中 是 的高八位, 是 的低八位。将式(4-5)代入式(4-4),经整理后得:
(4-6)
再设: (4-7)
其中 为整数, 为16位二进制余数。将式(4-7)代入式(4-6),如上类推,最后得:
(4-
很显然,十六位二进制数 既是我们要求的CRC码。
式(4 -7)是编写按字节计算CRC程序的关键,它说明计算本字节后的CRC码等于上一字节余式CRC码的低8位左移8位后,再加上上一字节CRC右移8位(也既取高8位)和本字节之和后所求得的CRC码,如果我们把8位二进制序列数的CRC全部计算出来,放如一个表里,采用查表法,可以大大提高计算速度。由此不难理解下面按字节求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,CRC余式表是按0x11021多项式求出的。
[code]
unsigned int cal_crc(unsigned char *ptr, unsigned char len) {
unsigned int crc;
unsigned char da;
unsigned int crc_ta[256]={ /* CRC余式表 */
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x 1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
crc=0;
while(len--!=0) {
da=(uchar) (crc/256); /* 以8位二进制数的形式暂存CRC的高8位 */
crc<<=8; /* 左移8位,相当于CRC的低8位乘以 */
crc^=crc_ta[da^*ptr]; /* 高8位和当前字节相加后再查表求CRC ,再加上以前的CRC */
ptr++;
}
return(crc);
}
很显然,按字节求CRC时,由于采用了查表法,大大提高了计算速度。但对于广泛运用的8位微处理器,代码空间有限,对于要求256个CRC余式表(共512字节的内存)已经显得捉襟见肘了,但CRC的计算速度又不可以太慢,因此再介绍下面一种按半字节求CRC的算法。
5 按半字节计算CRC
同样道理,对于一个二进制序列数可以按字节表示为式(5-1),其中 为半个字节(共4位)。
(5-1)
求此二进制序列数的CRC码时,先乘以 后(既左移16位),再除以多项式G(X),所得的余数既是所要求的CRC码。如式(4-2)所示:
(5-2)
可以设: (5-3)
其中 为整数, 为16位二进制余数。将式(5-3)代入式(5-2)得:
(5-4)
因为:
(5-5)
其中 是 的高4位, 是 的低12位。将式(5-5)代入式(5-4),经整理后得:
(5-6)
再设: (5-7)
其中 为整数, 为16位二进制余数。将式(5-7)代入式(5-6),如上类推,最后得:
(5-
很显然,十六位二进制数 既是我们要求的CRC码。
式(5 -7)是编写按字节计算CRC程序的关键,它说明计算本字节后的CRC码等于上一字节CRC码的低12位左移4位后,再加上上一字节余式CRC右移4位(也既取高4位)和本字节之和后所求得的CRC码,如果我们把4位二进制序列数的CRC全部计算出来,放在一个表里,采用查表法,每个字节算两次(半字节算一次),可以在速度和内存空间取得均衡。由此不难理解下面按半字节求CRC码的C语言程序。*ptr指向发送缓冲区的首字节,len是要发送的总字节数,CRC余式表是按0x11021多项式求出的。
unsigned cal_crc(unsigned char *ptr, unsigned char len) {
unsigned int crc;
unsigned char da;
unsigned int crc_ta[16]={ /* CRC余式表 */
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
}
crc=0;
while(len--!=0) {
da=((uchar)(crc/256))/16; /* 暂存CRC的高四位 */
crc<<=4; /* CRC右移4位,相当于取CRC的低12位)*/
crc^=crc_ta[da^(*ptr/16)]; /* CRC的高4位和本字节的前半字节相加后查表计算CRC,
然后加上上一次CRC的余数 */
da=((uchar)(crc/256))/16; /* 暂存CRC的高4位 */
crc<<=4; /* CRC右移4位, 相当于CRC的低12位) */
crc^=crc_ta[da^(*ptr&0x0f)]; /* CRC的高4位和本字节的后半字节相加后查表计算CRC,
然后再加上上一次CRC的余数 */
ptr++;
}
return(crc);
}
[code]
5 结束语
以上介绍的三种求CRC的程序,按位求法速度较慢,但占用最小的内存空间;按字节查表求CRC的方法速度较快,但占用较大的内存;按半字节查表求CRC的方法是前两者的均衡,即不会占用太多的内存,同时速度又不至于太慢,比较适合8位小内存的单片机的应用场合。以上所给的C程序可以根据各微处理器编译器的特点作相应的改变,比如把CRC余式表放到程序存储区内等。[/code]
hjzgq 回复于:2003-05-15 14:12:51
CRC32算法学习笔记以及如何用java实现 出自:csdn bootcool 2002年10月19日 23:11 CRC32算法学习笔记以及如何用java实现
CRC32算法学习笔记以及如何用java实现
一:说明
论坛上关于CRC32校验算法的详细介绍不多。前几天偶尔看到Ross N. Williams的文章,总算把CRC32算法的来龙去脉搞清楚了。本来想把原文翻译出来,但是时间参促,只好把自己的一些学习心得写出。这样大家可以更快的了解CRC32的主要思想。由于水平有限,还恳请大家指正。原文可以访问:http://www.repairfaq.org/filipg/LINK/F_crc_v31.html 。
二:基本概念及相关介绍
2.1 什么是CRC
在远距离数据通信中,为确保高效而无差错地传送数据,必须对数据进行校验即差错控制。循环冗余校验CRC(Cyclic Rendancy Check/Code)是对一个传送数据块进行校验,是一种高效的差错控制方法。
CRC校验采用多项式编码方法。多项式乘除法运算过程与普通代数多项式的乘除法相同。多项式的加减法运算以2为模,加减时不进,错位,如同逻辑异或运算。
2.2 CRC的运算规则
CRC加法运算规则:0+0=0
0+1=1
1+0=1
1+1=0 (注意:没有进位)
CRC减法运算规则:
0-0=0
0-1=1
1-0=1
1-1=0
CRC乘法运算规则:
0*0=0
0*1=0
1*0=0
1*1=1
CRC除法运算规则:
1100001010 (注意:我们并不关心商是多少。)
_______________
10011 11010110110000
10011,,.,,....
-----,,.,,....
10011,.,,....
10011,.,,....
-----,.,,....
00001.,,....
00000.,,....
-----.,,....
00010,,....
00000,,....
-----,,....
00101,....
00000,....
-----,....
01011....
00000....
-----....
10110...
10011...
-----...
01010..
00000..
-----..
10100.
10011.
-----.
01110
00000
-----
1110 = 余数
2.3 如何生成CRC校验码
(1) 设G(X)为W阶,在数据块末尾添加W个0,使数据块为M+ W位,则相应的多项式为XrM(X);
(2) 以2为模,用对应于G(X)的位串去除对应于XrM(X)的位串,求得余数位串;
(3) 以2为模,从对应于XrM(X)的位串中减去余数位串,结果就是为数据块生成的带足够校验信息的CRC校验码位串。
2.4 可能我们会问那如何选择G(x)
可以说选择G(x)不是一件很容易的事。一般我们都使用已经被大量的数据,时间检验过的,正确的,高效的,生成多项式。一般有以下这些:
16 bits: (16,12,5,0) [X25 standard]
(16,15,2,0) ["CRC-16"]
32 bits: (32,26,23,22,16,12,11,10,8,7,5,4,2,1,0) [Ethernet]
三: 如何用软件实现CRC算法
现在我们主要问题就是如何实现CRC校验,编码和解码。用硬件实现目前是不可能的,我们主要考虑用软件实现的方法。
以下是对作者的原文的翻译:
我们假设有一个4 bits的寄存器,通过反复的移位和进行CRC的除法,最终该寄存器中的值就是我们所要求的余数。
3 2 1 0 Bits
+---+---+---+---+
Pop <-- | | | | | <----- Augmented message(已加0扩张的原始数据)
+---+---+---+---+
1 0 1 1 1 = The Poly
(注意: The augmented message is the message followed by W zero bits.)
依据这个模型,我们得到了一个最最简单的算法:
把register中的值置0.
把原始的数据后添加r个0.
While (还有剩余没有处理的数据)
Begin
把register中的值左移一位,读入一个新的数据并置于register的0 bit的位置。
If (如果上一步的左移操作中的移出的一位是1)
register = register XOR Poly.
End
现在的register中的值就是我们要求的crc余数。
我的学习笔记:
可为什么要这样作呢?我们从下面的实例来说明:
1100001010
_______________
10011 11010110110000
10011,,.,,....
-----,,.,,....
-》 10011,.,,....
10011,.,,....
-----,.,,....
-》 00001.,,....
00000.,,....
-----.,,....
00010,,....
00000,,....
-----,,....
00101,....
00000,....
我们知道G(x)的最高位一定是1,而商1还是商0是由被除数的最高位决定的。而我们并不关心商究竟是多少,我们关心的是余数。例如上例中的G(x)有5 位。我们可以看到每一步作除法运算所得的余数其实就是被除数的最高位后的四位于G(x)的后四位XOR而得到的。那被除数的最高位有什么用呢?我们从打记号的两个不同的余数就知道原因了。当被除数的最高位是1时,商1然后把最高位以后的四位于G(x)的后四位XOR得到余数;如果最高位是0,商0然后把被除数的最高位以后的四位于G(x)的后四位XOR得到余数,而我们发现其实这个余数就是原来被除数最高位以后的四位的值。也就是说如果最高位是0就不需要作XOR的运算了。到这我们总算知道了为什么先前要这样建立模型,而算法的原理也就清楚了。
以下是对作者的原文的翻译:
可是这样实现的算法却是非常的低效。为了加快它的速度,我们使它一次能处理大于4 bit的数据。也就是我们想要实现的32 bit的CRC校验。我们还是假设有和原来一样的一个4 "bit"的register。不过它的每一位是一个8 bit的字节。
3 2 1 0 Bytes
+----+----+----+----+
Pop <-- | | | | | <----- Augmented message
+----+----+----+----+
1<------32 bits------> (暗含了一个最高位的“1”)
根据同样的原理我们可以得到如下的算法:
While (还有剩余没有处理的数据)
Begin
检查register头字节,并取得它的值
求不同偏移处多项式的和
register左移一个字节,最右处存入新读入的一个字节
把register的值和多项式的和进行XOR运算
End
我的学习笔记:
可是为什么要这样作呢? 同样我们还是以一个简单的例子说明问题:
假设有这样的一些值:
当前register中的值: 01001101
4 bit应该被移出的值:1011
生成多项式为: 101011100
Top Register
---- --------
1011 01001101
1010 11100 + (CRC XOR)
-------------
0001 10101101
首4 bits 不为0说明没有除尽,要继续除:
0001 10101101
1 01011100 + (CRC XOR)
-------------
0000 11110001
^^^^
首4 bits 全0说明不用继续除了。
那按照算法的意思作又会有什么样的结果呢?
1010 11100
1 01011100+
-------------
1011 10111100
1011 10111100
1011 01001101+
-------------
0000 11110001
现在我们看到了这样一个事实,那就是这样作的结果和上面的结果是一致的。这也说明了算法中为什么要先把多项式的值按不同的偏移值求和,然后在和 register进行异或运算的原因了。另外我们也可以看到,每一个头字节对应一个值。比如上例中:1011,对应01001101。那么对于 32 bits 的CRC 头字节,依据我们的模型。头8 bit就该有 2^8个,即有256个值与它对应。于是我们可以预先建立一个表然后,编码时只要取出输入数据的头一个字节然后从表中查找对应的值即可。这样就可以大大提高编码的速度了。
+----+----+----+----+
+-----< | | | | | <----- Augmented message
| +----+----+----+----+
| ^
| |
| XOR
| |
| 0+----+----+----+----+
v +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
+-----> +----+----+----+----+
+----+----+----+----+
+----+----+----+----+
+----+----+----+----+
+----+----+----+----+
255+----+----+----+----+
以下是对作者的原文的翻译:
上面的算法可以进一步优化为:
1:register左移一个字节,从原始数据中读入一个新的字节.
2:利用刚从register移出的字节作为下标定位 table 中的一个32位的值
3:把这个值XOR到register中。
4:如果还有未处理的数据则回到第一步继续执行。
用C可以写成这样:
r=0;
while (len--)
r = ((r << | p*++) ^ t[(r >> 24) & 0xFF];
可是这一算法是针对已经用0扩展了的原始数据而言的。所以最后还要加入这样的一个循环,把W个0加入原始数据。
我的学习笔记:
注意不是在预处理时先加入W个0,而是在上面算法描述的循环后加入这样的处理。
for (i=0; i<W/4; i++)
r = (r << ^ t[(r >> 24) & 0xFF];
所以是W/4是因为若有W个0,因为我们以字节(8位)为单位的,所以是W/4个0 字节。注意不是循环w/8次
以下是对作者的原文的翻译:
1:对于尾部的w/4个0字节,事实上它们的作用只是确保所有的原始数据都已被送入register,并且被算法处理。
2:如果register中的初始值是0,那么开始的4次循环,作用只是把原始数据的头4个字节送入寄存器。(这要结合table表的生成来看)。就算 register的初始值不是0,开始的4次循环也只是把原始数据的头4个字节把它们和register的一些常量XOR,然后送入register中。
3A xor B) xor C = A xor (B xor C)
总上所述,原来的算法可以改为:
+-----<Message (non augmented)
|
v 3 2 1 0 Bytes
| +----+----+----+----+
XOR----<| | | | |
| +----+----+----+----+
| ^
| |
| XOR
| |
| 0+----+----+----+----+
v +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
| +----+----+----+----+
+----->+----+----+----+----+
+----+----+----+----+
+----+----+----+----+
+----+----+----+----+
+----+----+----+----+
255+----+----+----+----+
算法:
1:register左移一个字节,从原始数据中读入一个新的字节.
2:利用刚从register移出的字节和读入的新字节XOR从而产生定位下标,从table中取得相应的值。
3:把该值XOR到register中
4:如果还有未处理的数据则回到第一步继续执行。
我的学习笔记:
对这一算法我还是不太清楚,或许和XOR的性质有关,恳请大家指出为什么?
谢谢。
到这,我们对CRC32的算法原理和思想已经基本搞清了。下章,我想着重根据算法思想用java语言实现。
hjzgq 回复于:2003-05-15 14:14:51
数学算法一向都是密码加密的核心,但在一般的软路加密中,它似乎并不太为人们所关心,因为大多数时候软体加密本身实现的都是一种编程上的技巧。但近几年来随着序列号加密程序的普及,数学算法在软体加密中的比重似乎是越来越大了。
我们先来看看在网路上大行其道的序列号加密的工作原理。当用户从网路上下载某个Shareware -- 共享软体后,一般都有使用时间上的限制,当过了共享软体的试用期后,你必须到这个软体的公司去注册后方能继续使用。注册过程一般是用户把自己的私人信息(一般主要指名字)连同信用卡号码告诉给软体公司,软体公司会根据用户的信息计算出一个序列码出来,在用户得到这个序列码后,按照注册需要的步骤在软体中输入注册信息和注册码,其注册信息的合法性由软体验证通过后,软体就会取消掉本身的各种限制。这种加密实现起来比较简单,不需要额外的成本,用户购买也非常方便,在网上的软体80%都是以这种方式来保护的。
我们可以注意到软体验证序列号的合法性过程,其实就是验证用户名与序列号之间的换算关系是否正确的过程。其验证最基本的有两种,一种是按用户输入的姓名来生成注册码,再同用户输入的注册码相比较,公式表示如下:
序列号 = F(用户名称)
❹ 用chembiodraw11画C60`(Fullerene),
画化学物质一般用的软件是Chemdraw,软件自带的一些常用芳环化合物中就有C60。
❺ W11如何下载C60
根据目前收集到的资料,要将 vc6Microsoft Visual StudioCommonMSDev98Bin 目录下的 MSDEV.EXE 文件重命名为 MSDEV1.EXE,然后右键这个文件属性,兼容性选项卡,把兼容模式的下拉框选择 Windows 7 或者 Windows XP (SP2),然后确定就可以运行了。但是此法未在本机 Win11 家庭版测试通过,仍然无法运行。
如果不是非计算机专业学二级C或者学校必须要求的话,不再建议在Win11中使用VC6。目前尚无Win11运行VC6的方法。一说修改msdev.exe的文件名可以运行,但这边实测无效。
建议使用Dev-C++、CLion、Code::Blocks、VS2019、VS2022这种更崭新的IDE环境。
❻ c语言在vc++下 编程的俄罗斯方源程序
以下代码来自 easyx 官网,已经测试过可以用,支持各版本 vc。需要安装 easyx 库才能编译。
项目直接建立控制台项目就好了。
////////////////////////////////////////////
//程序名称:俄罗斯方块
//编译环境:VisualC++6.0/2010,EasyX_v20131006(beta)
//程序编写:krissi<[email protected]>
//更新记录:2010-12-18 [email protected]编写
//2011-9-28 [email protected]修改了下落超时的逻辑
//[email protected]修改了绘制方法,将原来的立体效果修改为扁平效果
//
#include<easyx.h>
#include<conio.h>
#include<time.h>/////////////////////////////////////////////
//定义常量、枚举量、结构体、全局变量
/////////////////////////////////////////////
#define WIDTH 10 //游戏区宽度
#define HEIGHT 22 //游戏区高度
#define UNIT 20 //每个游戏区单位的实际像素
//定义操作类型
enumCMD
{
CMD_ROTATE, //方块旋转
CMD_LEFT,CMD_RIGHT,CMD_DOWN, //方块左、右、下移动
CMD_SINK, //方块沉底
CMD_QUIT //退出游戏
};
//定义绘制方块的方法
enumDRAW
{
SHOW, //显示方块
CLEAR, //擦除方块
FIX //固定方块
};
//定义七种俄罗斯方块
structBLOCK
{
WORDdir[4]; //方块的四个旋转状态
COLORREFcolor; //方块的颜色
} g_Blocks[7]={ {0x0F00,0x4444,0x0F00,0x4444,RED}, //I
{0x0660,0x0660,0x0660,0x0660,BLUE}, //口
{0x4460,0x02E0,0x0622,0x0740,MAGENTA}, //L
{0x2260,0x0E20,0x0644,0x0470,YELLOW}, //反L
{0x0C60,0x2640,0x0C60,0x2640,CYAN}, //Z
{0x0360,0x4620,0x0360,0x4620,GREEN}, //反Z
{0x4E00,0x4C40,0x0E40,0x4640,BROWN}}; //T
//定义当前方块、下一个方块的信息
structBLOCKINFO
{
byteid; //方块ID
charx,y; //方块在游戏区中的坐标
bytedir:2; //方向
} g_CurBlock,g_NextBlock;
//定义游戏区
BYTEg_World[WIDTH][HEIGHT]={0};/////////////////////////////////////////////
//函数声明
/////////////////////////////////////////////
voidInit(); //初始化游戏
voidQuit(); //退出游戏
voidNewGame(); //开始新游戏
voidGameOver(); //结束游戏
CMDGetCmd(); //获取控制命令
voidDispatchCmd(CMD_cmd); //分发控制命令
voidNewBlock(); //生成新的方块
boolCheckBlock(BLOCKINFO_block); //检测指定方块是否可以放下
voidDrawUnit(intx,inty,COLORREFc,DRAW_draw); //画单元方块
voidDrawBlock(BLOCKINFO_block,DRAW_draw=SHOW); //画方块
voidOnRotate(); //旋转方块
voidOnLeft(); //左移方块
voidOnRight(); //右移方块
voidOnDown(); //下移方块
voidOnSink(); //沉底方块/////////////////////////////////////////////
//函数定义
/////////////////////////////////////////////
//主函数
voidmain()
{
Init();
CMDc;
while(true)
{
c=GetCmd();
DispatchCmd(c);
//按退出时,显示对话框咨询用户是否退出
if(c==CMD_QUIT)
{
HWNDwnd=GetHWnd();
if(MessageBox(wnd,_T("您要退出游戏吗?"),_T("提醒"),MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
Quit();
}
}
}
//初始化游戏
voidInit()
{
initgraph(640,480);
srand((unsigned)time(NULL));
setbkmode(TRANSPARENT); //设置图案填充的背景色为透明
//显示操作说明
settextstyle(14,0,_T("宋体"));
outtextxy(20,330,_T("操作说明"));
outtextxy(20,350,_T("上:旋转"));
outtextxy(20,370,_T("左:左移"));
outtextxy(20,390,_T("右:右移"));
outtextxy(20,410,_T("下:下移"));
outtextxy(20,430,_T("空格:沉底"));
outtextxy(20,450,_T("ESC:退出"));
//设置坐标原点
setorigin(220,20);
//绘制游戏区边界
rectangle(-1,-1,WIDTH*UNIT,HEIGHT*UNIT);
rectangle((WIDTH+1)*UNIT-1,-1,(WIDTH+5)*UNIT,4*UNIT);
//开始新游戏
NewGame();
}
//退出游戏
voidQuit()
{
closegraph();
exit(0);
}
//开始新游戏
voidNewGame()
{
//清空游戏区
setfillcolor(BLACK);
solidrectangle(0,0,WIDTH*UNIT-1,HEIGHT*UNIT-1);
ZeroMemory(g_World,WIDTH*HEIGHT);
//生成下一个方块
g_NextBlock.id=rand()%7;
g_NextBlock.dir=rand()%4;
g_NextBlock.x=WIDTH+1;
g_NextBlock.y=HEIGHT-1;
//获取新方块
NewBlock();
}
//结束游戏
voidGameOver()
{
HWNDwnd=GetHWnd();
if(MessageBox(wnd,_T("游戏结束。 您想重新来一局吗?"),_T("游戏结束"),MB_YESNO|MB_ICONQUESTION)==IDYES)
NewGame();
else
Quit();
}
//获取控制命令
DWORDm_oldtime;
CMDGetCmd()
{
//获取控制值
while(true)
{
//如果超时,自动下落一格
DWORDnewtime=GetTickCount();
if(newtime-m_oldtime>=500)
{
m_oldtime=newtime;
returnCMD_DOWN;
}
//如果有按键,返回按键对应的功能
if(kbhit())
{
switch(getch())
{
case'w':
case'W': returnCMD_ROTATE;
case'a':
case'A': returnCMD_LEFT;
case'd':
case'D': returnCMD_RIGHT;
case's':
case'S': returnCMD_DOWN;
case27: returnCMD_QUIT;
case'': returnCMD_SINK;
case0:
case0xE0:
switch(getch())
{
case72: returnCMD_ROTATE;
case75: returnCMD_LEFT;
case77: returnCMD_RIGHT;
case80: returnCMD_DOWN;
}
}
}
//延时(降低CPU占用率)
Sleep(20);
}
}
//分发控制命令
voidDispatchCmd(CMD_cmd)
{
switch(_cmd)
{
caseCMD_ROTATE: OnRotate(); break;
caseCMD_LEFT: OnLeft(); break;
caseCMD_RIGHT: OnRight(); break;
caseCMD_DOWN: OnDown(); break;
caseCMD_SINK: OnSink(); break;
caseCMD_QUIT: break;
}
}
//生成新的方块
voidNewBlock()
{
g_CurBlock.id=g_NextBlock.id, g_NextBlock.id=rand()%7;
g_CurBlock.dir=g_NextBlock.dir, g_NextBlock.dir=rand()%4;
g_CurBlock.x=(WIDTH-4)/2;
g_CurBlock.y=HEIGHT+2;
//下移新方块直到有局部显示
WORDc=g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];
while((c&0xF)==0)
{
g_CurBlock.y--;
c>>=4;
}
//绘制新方块
DrawBlock(g_CurBlock);
//绘制下一个方块
setfillcolor(BLACK);
solidrectangle((WIDTH+1)*UNIT,0,(WIDTH+5)*UNIT-1,4*UNIT-1);
DrawBlock(g_NextBlock);
//设置计时器,用于判断自动下落
m_oldtime=GetTickCount();
}
//画单元方块
voidDrawUnit(intx,inty,COLORREFc,DRAW_draw)
{
//计算单元方块对应的屏幕坐标
intleft=x*UNIT;
inttop=(HEIGHT-y-1)*UNIT;
intright=(x+1)*UNIT-1;
intbottom=(HEIGHT-y)*UNIT-1;
//画单元方块
switch(_draw)
{
caseSHOW:
//画普通方块
setlinecolor(0x006060);
roundrect(left+1,top+1,right-1,bottom-1,5,5);
setlinecolor(0x003030);
roundrect(left,top,right,bottom,8,8);
setfillcolor(c);
setlinecolor(LIGHTGRAY);
fillrectangle(left+2,top+2,right-2,bottom-2);
break;
caseFIX:
//画固定的方块
setfillcolor(RGB(GetRValue(c)*2/3,GetGValue(c)*2/3,GetBValue(c)*2/3));
setlinecolor(DARKGRAY);
fillrectangle(left+1,top+1,right-1,bottom-1);
break;
caseCLEAR:
//擦除方块
setfillcolor(BLACK);
solidrectangle(x*UNIT,(HEIGHT-y-1)*UNIT,(x+1)*UNIT-1,(HEIGHT-y)*UNIT-1);
break;
}
}
//画方块
voidDrawBlock(BLOCKINFO_block,DRAW_draw)
{
WORDb=g_Blocks[_block.id].dir[_block.dir];
intx,y;
for(inti=0;i<16;i++,b<<=1)
if(b&0x8000)
{
x=_block.x+i%4;
y=_block.y-i/4;
if(y<HEIGHT)
DrawUnit(x,y,g_Blocks[_block.id].color,_draw);
}
}
//检测指定方块是否可以放下
boolCheckBlock(BLOCKINFO_block)
{
WORDb=g_Blocks[_block.id].dir[_block.dir];
intx,y;
for(inti=0;i<16;i++,b<<=1)
if(b&0x8000)
{
x=_block.x+i%4;
y=_block.y-i/4;
if((x<0)||(x>=WIDTH)||(y<0))
returnfalse;
if((y<HEIGHT)&&(g_World[x][y]))
returnfalse;
}
returntrue;
}
//旋转方块
voidOnRotate()
{
//获取可以旋转的x偏移量
intdx;
BLOCKINFOtmp=g_CurBlock;
tmp.dir++; if(CheckBlock(tmp)) { dx=0; gotorotate; }
tmp.x=g_CurBlock.x-1; if(CheckBlock(tmp)) { dx=-1; gotorotate; }
tmp.x=g_CurBlock.x+1; if(CheckBlock(tmp)) { dx=1; gotorotate; }
tmp.x=g_CurBlock.x-2; if(CheckBlock(tmp)) { dx=-2; gotorotate; }
tmp.x=g_CurBlock.x+2; if(CheckBlock(tmp)) { dx=2; gotorotate; }
return;
rotate:
//旋转
DrawBlock(g_CurBlock,CLEAR);
g_CurBlock.dir++;
g_CurBlock.x+=dx;
DrawBlock(g_CurBlock);
}
//左移方块
voidOnLeft()
{
BLOCKINFOtmp=g_CurBlock;
tmp.x--;
if(CheckBlock(tmp))
{
DrawBlock(g_CurBlock,CLEAR);
g_CurBlock.x--;
DrawBlock(g_CurBlock);
}
}
//右移方块
voidOnRight()
{
BLOCKINFOtmp=g_CurBlock;
tmp.x++;
if(CheckBlock(tmp))
{
DrawBlock(g_CurBlock,CLEAR);
g_CurBlock.x++;
DrawBlock(g_CurBlock);
}
}
//下移方块
voidOnDown()
{
BLOCKINFOtmp=g_CurBlock;
tmp.y--;
if(CheckBlock(tmp))
{
DrawBlock(g_CurBlock,CLEAR);
g_CurBlock.y--;
DrawBlock(g_CurBlock);
}
else
OnSink(); //不可下移时,执行“沉底方块”操作
}
//沉底方块
voidOnSink()
{
inti,x,y;
//连续下移方块
DrawBlock(g_CurBlock,CLEAR);
BLOCKINFOtmp=g_CurBlock;
tmp.y--;
while(CheckBlock(tmp))
{
g_CurBlock.y--;
tmp.y--;
}
DrawBlock(g_CurBlock,FIX);
//固定方块在游戏区
WORDb=g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];
for(i=0;i<16;i++,b<<=1)
if(b&0x8000)
{
if(g_CurBlock.y-i/4>=HEIGHT)
{ //如果方块的固定位置超出高度,结束游戏
GameOver();
return;
}
else
g_World[g_CurBlock.x+i%4][g_CurBlock.y-i/4]=1;
}
//检查是否需要消掉行,并标记
BYTEremove=0; //低4位用来标记方块涉及的4行是否有消除行为
for(y=g_CurBlock.y;y>=max(g_CurBlock.y-3,0);y--)
{
i=0;
for(x=0;x<WIDTH;x++)
if(g_World[x][y]==1)
i++;
if(i==WIDTH)
{
remove|=(1<<(g_CurBlock.y-y));
setfillcolor(LIGHTGREEN);
setlinecolor(LIGHTGREEN);
setfillstyle(BS_HATCHED,HS_DIAGCROSS);
fillrectangle(0,(HEIGHT-y-1)*UNIT+UNIT/2-5,WIDTH*UNIT-1,(HEIGHT-y-1)*UNIT+UNIT/2+5);
setfillstyle(BS_SOLID);
}
}
if(remove) //如果产生整行消除
{
//延时300毫秒
Sleep(300);
//擦掉刚才标记的行
IMAGEimg;
for(i=0;i<4;i++,remove>>=1)
{
if(remove&1)
{
for(y=g_CurBlock.y-i+1;y<HEIGHT;y++)
for(x=0;x<WIDTH;x++)
{
g_World[x][y-1]=g_World[x][y];
g_World[x][y]=0;
}
getimage(&img,0,0,WIDTH*UNIT,(HEIGHT-(g_CurBlock.y-i+1))*UNIT);
putimage(0,UNIT,&img);
}
}
}
//产生新方块
NewBlock();
}
❼ 动软代码生成器可以生成到wps吗
请参看下面的图文教程《动软代码生成器怎么用-动软代码生成器教程》http://jingyan..com/article/e52e3615a3c98e40c60c5129.html
1. 系统要求:Microsoft Windows2000/XP/2003/7 或者更高。机器必须安装.NET Framework v2.0。
2. 官方下载地址:http://www.maticsoft.com/download.aspx
3. 下载解压后安装包有如下文件,如图:
Codematic2.msi 是动软.NET代码生成器的安装文件。
Builder文件夹是代码生成插件的源码,动软.NET代码生成器支持可扩展的代码生成插件,用户可以定制自己的代码生成的插件,根据接口开发自己的代码生成方式,按自己的需求进行代码生成。
Codematic_Data.MDF和Codematic_Log.LDF是通过动软新建项目中所带管理模块所需要的数据库文件。后台管理员默认登录用户名:admin 密码:1
2
安装
1.双击Codematic2.msi 进行直接安装即可。安装动软时,如果用户机器360弹出警告,那仅仅是个签名认证提示,并非木马,选择“继续安装”,然后点击“确定”即可。
2.安装成功后,在开始-菜单和桌面上会有动软.NET代码生成器的图标。
3
在软件界面的左侧数据库视图窗口,选择【服务器】,右键出现菜单或 点击第1个按钮如图红框内
4
选择【添加服务器】,然后,出现“选择数据库类型”窗口
5
根据自己的实际情况,选择一个机器上有的或自己项目中在用的数据库类型。并确保你选择的数据库是可以正常访问的。然后,【下一步】。
如果选择的是SQL Server,则会出现如图所示界面:
注意事项:
(1) 输
入服务器IP地址,如果是本机也可以是:(local) 或是. 或者
127.0.0.1。 如果服务器并非只有一个默认实例,请采用:服务器\实例名的方式连接。(2)一定要选择和实际数据库服务器版本一致的选项,
否则会导致连接数据库错误。注意:请使用SQLServer的企业版或正式版本,不能是SQL
EXPRESS版,否则无法连接。(3)身份验证可以选择是SQLServer认证,还是Windows认证。
(4)输入数据库服务器用户
名密码。如果不知道,请联系你的数据库管理员。(5)如果数据库的表比较多,连接速度会比较慢,启用【高效连接模式】实现快速连接。(6)可以通过【连接
/测试】,来连接服务器并获取数据库列表,从而可以实现只选择连接一个库进行操作,减少不必要的连接时间,提高工作效率。
6
如果选择的是Oracle,出现如图所示界面;
输入您自己安装过的Oracle的管理员用户名和密码,服务就是安装的Oracle服务名,一般默认是Oracle所在的机器名,如果不确定,请联系您的数据库管理员。
7
如果选择的是MySQL,出现如图所示界面
8
如果选择的是Oledb出现如图所示界面;
在地址文本框,可以直接输入Access库的文件地址,注意:库文件尽量不要放在桌面,并且确保你的文件地址正确。如果你的Access并没有设置密码,下面的密码可以不用管。
9
如果选择的是SQLite,出现如图所示界面
10
在以上步骤确定后,动软.NET代码生成器的数据库视图就出现了数据库服务器的信息。如图所示
11
在数据库上右键,【浏览数据库】,通过选择库和表可以查看表和字段的信息。
12
选择【新建查询】菜单,即出现SQL的查询分析器窗口,可以输入SQL语句进行查询。
13
在表上,右键选择【浏览表数据】,可以查看表的数据内容。
14
新建整个项目
在看过了基本的数据库管理功能之外,下面我们就可以开始生成代码了。
首先,一般第一次生成,我们要生成的是整个项目框架。
选中数据库,然后右键:【新建NET项目】,或者直接点工具栏上的快捷图标均可。
15
然后,选择项目类型和版本:如图所示;
l 简单三层结构:生成标准的三层架构项目。
l 工厂模式结构:生成基于工厂模式的项目架构,适合一个项目多数据库类型的情况。
l 简单三层结构(管理):生成标准的三层架构项目,并且带有基本的系统管理功能和界面,这些通用的功能主要是节省开发人员的时间,可以在此基础上直接去开发自身业务模块。
这里暂以“简单三层结构(管理)”为例进行说明。
16
点击【下一步】,选择要生成的表和配置:如图所示;
双击选择要生成的表,选到右侧列表框。然后点击【开始生成】即可。
如果需要修改一些配置可以修改你自己的命名空间名字,是否去掉表的前缀。
代码模板组件类型,一般初学者建议默认即可。
相关组件说明:
BuilderDALParam 数据访问层(DAL)基于Parameter方式的代码生成组件(推荐)
BuilderDALProc 数据访问层(DAL)基于存储过程方式的代码生成组件
BuilderDALSQL 数据访问层(DAL)基于SQL拼接方式的代码生成组件
BuilderDALTranParam 数据访问层(DAL)带有事务的代码生成组件
DAL由于不同项目要求不同,根据项目需求,选择其中一种方式即可。
BuilderBLLComm 基于标准的业务逻辑层代码(BLL)
BuilderModel Model层的代码生成组件
BuilderWeb 表示层的代码生成组件
备注:代码还有一些生成规则,是在菜单【工具】-【选项】-【代码生成设置】中进行设置。
17
点击【开始生成】,则开始进行代码的生成,直到出现“项目工程生成成功”提示,项目生成完毕,如图所示;
18
打开生成的文件夹,如图所示;
19
双击解决方案文件,打开整个项目如图所示;
注:
“简单三层结构”目前暂时是VS2005版本,是为了兼容当前还在用2005的朋友。如果你使用的是VS2008,生成项目后,请先打开VS2008,选
择【菜单-文件-打开项目】的方式打开该项目,此时会提示升级项目版本,选择升级一下项目版本到VS2008或VS2010即可,对代码没有任何影响。
20
打开Web项目,选中刚才选择生成的那几个表的页面文件夹,右键【包括在项目中】,如图所示;
21
打开web项目下web.config修改数据库连接字符串,如图所示;
注意:新建项目后,请记得先将安装包里附带的数据库文件Codematic_Data.MDF 附加到SQLServer中。
如果需要加密,可以使用安装包里的加解密工具(官方下载该工具)。
然后,选择解决方案进行重新生成整个解决方案。整个创建项目过程即全部完成。如图所示;
如果编译没有错误, 直接按F5键运行即可。整个创建项目过程即全部完成。
运行启动登录页面login.aspx,输入用户名:admin,密码:1
即登录动软系统框架的后台,界面如下
批量代码生成
新建项目功能只适合于第一次,因为不可能每次都新建项目,特别是项目已经在开发中。所以,以后的项目开发中更多的应用的是【批量代码生成】功能。批量代码生成特别适合项目后期追加代码时使用。
选中数据库或者表,然后单击右键菜单【代码批量生成】,如图所示;
出现的窗口和新建项目基本相似,只是多了一个选中架构的选项。如图所示;
备注:代码还有一些生成规则,是在菜单【工具】-【选项】-【代码生成设置】中进行设置。
选则要生成的表,然后点击【导出】
在生成的文件夹中,我们可以看到:如图所示
批量生成代码只生成业务表的代码,不再有解决方案文件和项目文件,以及其它类库等。我们可以将生成的这些文件直接拖到现有的解决方案中即可。
单表代码生成
除了新建项目和批量代码生成,偶尔我们希望更个性化自定义一些代码生成的字段,而不是全部的自动生成,这是我们可以考虑针对单表的代码生成。
在左侧【数据库视图】,选中表,右键菜单【单表代码生成器】,如图所示
然后,出现单表的代码生成器界面,我们设置自己需要更改的信息。如图所示;
选项说明:
Ø 项目名称:主要用在生成DB脚本中。
Ø 二级命名空间:指的是这个类放在某一个二级文件夹下,从而命名空间中应该带这个文件夹的名字。
Ø 顶级命名空间:就是项目的命名空间名称。
Ø 类名:可以自己根据表名定义自己需要的名字。
Ø 类型:主要是生成什么代码,DB脚本主要生成表的存储过程和表的创建脚本及数据脚本。
Ø 架构选择:目前仅支持这3种最常用的架构。
Ø 代码类型:指生成指定架构中具体某一个项目中的代码。
Ø 代码模板组件类型:指生成代码的方式,因为即使同一个代码有很多的写法,组件主要实现的是不同的写法,但每种写法实现的功能都是一样的。主要看项目需要和个人习惯进行选择。
Ø 方法选择:指生成最基本的增删改查的方法代码,后续版本将支持用户自定义这些方法。
备注:代码还有一些生成规则,是在菜单【工具】-【选项】-【代码生成设置】中进行设置。
然后,点击【生成代码】按钮,即可生成该类的代码,如图所示;
生成的代码,可以直接复制到项目文件中,也可以右键保存成CS文件。
通过窗体下面的Tab按钮可以来回切换设计视图和代码。
代码生成规则设置
打开菜单【工具】-【选项】-【代码生成设置】
这些配置保存后,在生成代码的时候将按照这个规则进行生成。
代码生成的规则设置范围还在不断增加中。
另外,不同数据库类型的数据类型各有不同,这里提供了字段类型和C#中的类型建立映射关系,生成代码时将按映射关系来生成代码字段属性的类型。
❽ vscode怎么创建c项目
vscode怎样编写c程序?
一、获取C/C++扩展
1、打开vscode
2、ctrl+shift+x打开商店
3、搜索C/C++安装、重启vscode
.png
二、安装GCC
1、下载MinGW
2、打开安装程序,安装到D盘(需要创建MinGW文件夹),安装完成之后生成MinGW安装管理器
3、管理器自动打开(如果没有请手动),点击All Packages,选中gcc.bin,g++.bin,gdb.bin,点击Installation,选择Apply Changes,点击Apply提交进行安装
.png
win+R,输入control进入控制面板,依次点击系统与安装->系统->高级系统设置->环境变量,找到Path->编辑->新建,将安装好的MinGW的bin文件夹路径粘贴进去。
.png
三、配置智能提示
1、编写一个测试文件demo.c,点击引入的标准库下的“提示灯”,生成c_cpp_properties.json文件
2、编辑c_cpp_properties.json
.png
c_cpp_properties.json修改内容如下:
.png
四、开启调试功能
F5或Ctrl+F5启用调试,选择C++(GDB/LLDB)生成launch.json文件,修改如下:
Ctrl+Shift+P输入Tasks:Configure Task配置任务,选择使用模块创建task.json文件,选择Others模板,生成task.json文件,修改如下:
如果出现错误:进程终止,退出代码:1,可能是gcc还没被编辑器加载(测试方法:打开控制台,输入gcc,看提示信息),重启编辑器就可以。