本文将利用C语言和VHDL语言分别实现DES加密,并在8051和FPGA上测试。

终于有机会阅读《深入浅出密码学一书》,趁此机会深入研究了DES加密的思想与实现。本文将分为两部分,第一部分为简单的C语言实现,第二部分为FPGA实现并在NIOS II核上测试该模块。

DES加密的思想

DES加密的由来网络上资料非常了,这里给出wikipedia链接: 维基百科

DES加密主要利用了两个工具

  • 利用替换来实现混淆,如DES加密中的S_box ,即将明文和密文之间存在的关系尽可能模糊。

  • 利用位置换来实现扩散,如DES加密中的IP 。实现扩散之后,可以隐藏明文的统计属性,即一个明文符号的改变会涉及到多个密文符号的加密操作。

DES利用的流程为 Feistel网络 该网络主要特点为加密过程和解密过程几乎完全相同。

DES加密的C语言实现

利用C语言实现DES加密分为几个步骤:

  • 第一步先将上文中所描述的 替换位置换 先实现。

  • 第二步实现 f函数 以及 子密钥生成

  • 最后实现完整的 DES加密 操作

下面分步骤实现这些部分

替换实现

替换利用C语言来实现并不复杂,可以直接用数组实现,例如 S-box 实现可以如下

for (i = 0; i < 8; i++){
e_string[i] = (e_string[i] ^ round_key[i]) & 0x3F;
e_string[i] = s[i] [e_string[i]];
}

位置换实现

位置换相对就复杂,抽象出一个函数,传入置换表和置换位数。根据置换表中描述的位数查看对应位是否为1。若为1,则在输出表中将对应位置为1。

/** transpose
* This function is going to use table to transpose trans_in_data into trans_out_data,
* while n is the number of bit which trans_out_data have.
* @Author Liu Nian, 2017
*/
void transpose(unsigned char *trans_in_data, unsigned char *trans_out_data,
unsigned char *table, unsigned char n){
int i, bit_change;
//clear trans_out_data
for(i = 0; i < 8;i++)
trans_out_data[i] = 0;
//To transpose the bit_change bit
for(i = 0; i < n;i++){
bit_change = *table++;
//find the bit and check whether it is 1
if (trans_in_data[bit_change>>3] & (0x80>>(bit_change & 7)))
trans_out_data[i>>3] |= (0x80>>(i & 7));
}
}

f函数实现

利用上述两个方法可以实现f函数,f函数实现如下:

/** f
* This function is going to mix round_key with 32-bit string.
* @Author Liu Nian, 2017
*/
void f(unsigned char *round_key, unsigned char *in_string, unsigned char *xor_string){
unsigned char e_string[8];
int i;
transpose(in_string, e_string, E_table, 64);
//Use S box for confussion
for (i = 0; i < 8; i++){
e_string[i] = (e_string[i] ^ round_key[i]) & 0x3F;
e_string[i] = s[i] [e_string[i]];
}
transpose(e_string, xor_string, P_table, 32);
}

16轮子密钥生成

子密钥生成时,还用到了另一个工具,就是1,2,9,16轮加密时,左右32-bit密钥向左轮转1位,剩余情况则轮转2位。轮转用rotate_left 函数来实现。

/** rotate_left
* This function is going to make both left (32-bit) and right part of key rotate 1 bit.
* @Author Liu Nian, 2017
*/
void rotate_left(unsigned char *key){
unsigned char str_x[8];
unsigned char i;
for (i=0; i < 8; ++i)
str_x[i] = key[i];
for (i=0; i < 7; ++i){
key[i] = (key[i] << 1);
if ((i < 6) && ((str_x[i+1] & 128) == 128))
key[i] |= 1;
}
if (str_x[0] & 0x80 )
key[3] |= 0x10;
else
key[3] &= ~0x10;
if (str_x[3] & 0x08 )
key[6] |= 0x01;
else
key[6] &= ~0x01;
}

计算子密钥函数如下:

/** compute_subkeys
* This function is going to generate sub_keys.
* @Author Liu Nian, 2017
*/
void compute_subkeys(unsigned char *key){
unsigned char i, j, in_key[8], out_key[8];
// Store key in main_key
for (i=0; i < 8; i++)
main_key[i] = key[i];
// Use PC_1_table to transpose 64-bit key into 56-bit in_key
transpose(key, in_key, PC_1_table, 56);
//Generate sub_keys for every round
for (i=0; i < 16; i++){
//For round 1,2,9,16 , key has to be rotate left 1 bit
//For other rounds, key has to rotate left 2 bit
for (j=0; j < round_turn[i]; j++)
rotate_left(in_key);
// Use PC_2_table to transpose in_key to out_key
transpose(in_key, out_key, PC_2_table, 64);
for (j=0; j < 8; j++)
sub_keys[i][j] = out_key[j];
}
}

DES加密函数

将上述模块连接起来,完整整体DES加密。

/** DES function
* This function is used for DES encryption
* Input parameter
* unsigned char *plain_strng : pointer to 64 bits input string
* unsigned char *key : pointer to 64 bits key string
* unsigned char *ciph_strng : pointer to a 64 bits output string
* @Author Liu Nian, 2017
*/
void des(unsigned char *plain_strng, unsigned char *key, unsigned char *ciph_strng){
unsigned char in_string[8], round_string[8], xor_string[8];
unsigned char i, j, *round_key, temp;
// compute subkeys which will be used in every round
compute_subkeys(key);
// Use transpose plain_strng into in_string
transpose(plain_strng, in_string, IP_table, 64);
// Encrypt for 16 round
for (i = 0; i < 16; i++){
// round_string is string which we will deal with in this round.
for (j=0; j < 8; j++)
round_string[j] = in_string[j];
// round_key is the key which will be used in this round
round_key = &sub_keys[i][0];
// The first 32-bit of the next round string is the same as the last 32-bit of
// this round.
for (j=0; j < 4; j++)
in_string[j] = round_string[j+4];
// Use f box to generate xor_string
f(round_key, in_string, xor_string);
// The last 32-bit of the next round string is the result of XOR between
// the fist 32-bit of this round and xor_string
for (j=0; j < 4; j++)
in_string[j+4] = round_string[j] ^ xor_string[j];
}
// change the sequence of first 32-bit and last 32-bit
for (j=0; j < 4; j++) {
temp = in_string[j];
in_string[j] = in_string[j+4];
in_string[j+4] = temp;
}
// Use IP_1_table to transpose in_string into ciph_strng
transpose(in_string, ciph_strng, IP_1_table, 64);
}

完整代码见附

DES加密的FPGA实现

DES加密的FPGA实现参考CoreTex Systems 公司的版本。

主要思想是利用状态机来在各个状态之间进行转移。详细代码可以参见CoreTex Systems

详细分析待后补充。

接入NIOS II核心并测试

由于NIOS II 核心只支持 32-bitPIO 的外设,故输入输出拆成2个32位 端口实现。

Qsys 编辑界面如下:

在顶层图上添加DES加密模块 如下:

测试代码如下:


#include <stdio.h>
#include "system.h"
#include "altera_avalon_pio_regs.h" int main(){
int i = 0x0A;
unsigned int key_low = 0x12341234;
unsigned int key_high = 0x12341234;
unsigned int data_high = 0x01020304 ;
unsigned int data_low = 0x05060708;
unsigned int out_low;
unsigned int out_high;
int des_state = 0;
printf("Des_test\n");
IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE,i);
IOWR_ALTERA_AVALON_PIO_DATA(KEY_OUT_LOW_BASE,key_low);
IOWR_ALTERA_AVALON_PIO_DATA(KEY_OUT_HIGH_BASE,key_high);
IOWR_ALTERA_AVALON_PIO_DATA(DATA_OUT_HIGH_BASE,data_high);
IOWR_ALTERA_AVALON_PIO_DATA(DATA_OUT_LOW_BASE,data_low);
printf("Start des\n");
//密钥明文传输完成,LD_DATA置1通知DES加密元件
IOWR_ALTERA_AVALON_PIO_DATA(LD_DATA_BASE,1); //等待加密完成
des_state = IORD_ALTERA_AVALON_PIO_DATA(DES_STATE_BASE);
printf("des_state:%d\n",des_state);
while(des_state & 0x1 == 0){
printf("des_state:%d\n",des_state);
usleep(10000);
des_state = IORD_ALTERA_AVALON_PIO_DATA(DES_STATE_BASE);
}
//输出加密结果
out_low = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_LOW_BASE);
out_high = IORD_ALTERA_AVALON_PIO_DATA(DATA_IN_HIGH_BASE);
printf("%x",out_high);
printf("%x",out_low);
return 0;
}

DES 加密C语言完整代码

#include <stdio.h>

/****************************************************************************************/
/* Translation Table */
/****************************************************************************************/
xdata const unsigned char 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
}; xdata const unsigned char 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
}; xdata const unsigned char swap[64] =
{
33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 62, 63, 64,
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32
}; xdata const unsigned char PC_1_table[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
}; xdata const unsigned char PC_2_table[64] =
{
0, 0, 13, 4, 16, 10, 23, 0,
0, 0, 2, 9, 27, 14, 5, 20,
0, 0, 22, 7, 18, 11, 3, 25,
0, 0, 15, 1, 6, 26, 19, 12,
0, 0, 40, 54, 51, 30, 36, 46,
0, 0, 29, 47, 39, 50, 44, 32,
0, 0, 43, 52, 48, 38, 55, 33,
0, 0, 45, 31, 41, 49, 35, 28
}; xdata const unsigned char E_table[64] =
{
0, 0, 31, 4, 0, 1, 2, 3,
0, 0, 3, 8, 4, 5, 6, 7,
0, 0, 7, 12, 8, 9, 10, 11,
0, 0, 11, 16, 12, 13, 14, 15,
0, 0, 15, 20, 16, 17, 18, 19,
0, 0, 19, 24, 20, 21, 22, 23,
0, 0, 23, 28, 24, 25, 26, 27,
0, 0, 27, 0, 28, 29, 30, 31
}; xdata const unsigned char P_table[32] =
{
31, 14, 39, 44, 60, 23, 55, 36,
4, 30, 46, 53, 12, 37, 62, 21,
5, 15, 47, 29, 63, 54, 6, 20,
38, 28, 61, 13, 45, 22, 7, 52
}; /****************************************************************************************/
/* S Box */
/****************************************************************************************/
xdata const unsigned char s[8][64] ={
{
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
},
{
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
},
{
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
},
{
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
},
{
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
},
{
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
},
{
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
},
{
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
}
}; xdata const unsigned char round_turn[16] ={
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
}; unsigned char DES_Encrypt_key[8];
unsigned char DES_Decrypt_key[8];
unsigned char sub_keys[16][8];
unsigned char main_key[8]; void des(unsigned char*, unsigned char*, unsigned char*);
static void transpose (unsigned char*, unsigned char*, const unsigned char*, unsigned char);
static void rotate_left (unsigned char*);
static void compute_subkeys (unsigned char*);
static void f (unsigned char*, unsigned char*, unsigned char*); /** DES function
* This function is used for DES encryption
* Input parameter
* unsigned char *plain_strng : pointer to 64 bits input string
* unsigned char *key : pointer to 64 bits key string
* unsigned char *ciph_strng : pointer to a 64 bits output string
* @Author Liu Nian, 2017
*/
void des(unsigned char *plain_strng, unsigned char *key, unsigned char *ciph_strng){
unsigned char in_string[8], round_string[8], xor_string[8];
unsigned char i, j, *round_key, temp;
// compute subkeys which will be used in every round
compute_subkeys(key);
// Use transpose plain_strng into in_string
transpose(plain_strng, in_string, IP_table, 64);
// Encrypt for 16 round
for (i = 0; i < 16; i++){
// round_string is string which we will deal with in this round.
for (j=0; j < 8; j++)
round_string[j] = in_string[j];
// round_key is the key which will be used in this round
round_key = &sub_keys[i][0];
// The first 32-bit of the next round string is the same as the last 32-bit of
// this round.
for (j=0; j < 4; j++)
in_string[j] = round_string[j+4];
// Use f box to generate xor_string
f(round_key, in_string, xor_string);
// The last 32-bit of the next round string is the result of XOR between
// the fist 32-bit of this round and xor_string
for (j=0; j < 4; j++)
in_string[j+4] = round_string[j] ^ xor_string[j];
}
// change the sequence of first 32-bit and last 32-bit
for (j=0; j < 4; j++) {
temp = in_string[j];
in_string[j] = in_string[j+4];
in_string[j+4] = temp;
}
// Use IP_1_table to transpose in_string into ciph_strng
transpose(in_string, ciph_strng, IP_1_table, 64);
} /** transpose
* This function is going to use table to transpose trans_in_data into trans_out_data,
* while n is the number of bit which trans_out_data have.
* @Author Liu Nian, 2017
*/
void transpose(unsigned char *trans_in_data, unsigned char *trans_out_data,
unsigned char *table, unsigned char n){
int i, bit_change;
//clear trans_out_data
for(i = 0; i < 8;i++)
trans_out_data[i] = 0;
//To transpose the bit_change bit
for(i = 0; i < n;i++){
bit_change = *table++;
//find the bit and check whether it is 1
if (trans_in_data[bit_change>>3] & (0x80>>(bit_change & 7)))
trans_out_data[i>>3] |= (0x80>>(i & 7));
}
} /** rotate_left
* This function is going to make both left (32-bit) and right part of key rotate 1 bit.
* @Author Liu Nian, 2017
*/
void rotate_left(unsigned char *key){
unsigned char str_x[8];
unsigned char i;
for (i=0; i < 8; ++i)
str_x[i] = key[i];
for (i=0; i < 7; ++i){
key[i] = (key[i] << 1);
if ((i < 6) && ((str_x[i+1] & 128) == 128))
key[i] |= 1;
}
if (str_x[0] & 0x80 )
key[3] |= 0x10;
else
key[3] &= ~0x10;
if (str_x[3] & 0x08 )
key[6] |= 0x01;
else
key[6] &= ~0x01;
} /** compute_subkeys
* This function is going to generate sub_keys.
* @Author Liu Nian, 2017
*/
void compute_subkeys(unsigned char *key){
unsigned char i, j, in_key[8], out_key[8];
// Store key in main_key
for (i=0; i < 8; i++)
main_key[i] = key[i];
// Use PC_1_table to transpose 64-bit key into 56-bit in_key
transpose(key, in_key, PC_1_table, 56);
//Generate sub_keys for every round
for (i=0; i < 16; i++){
//For round 1,2,9,16 , key has to be rotate left 1 bit
//For other rounds, key has to rotate left 2 bit
for (j=0; j < round_turn[i]; j++)
rotate_left(in_key);
// Use PC_2_table to transpose in_key to out_key
transpose(in_key, out_key, PC_2_table, 64);
for (j=0; j < 8; j++)
sub_keys[i][j] = out_key[j];
}
} /** f
* This function is going to mix round_key with 32-bit string.
* @Author Liu Nian, 2017
*/
void f(unsigned char *round_key, unsigned char *in_string, unsigned char *xor_string){
unsigned char e_string[8];
int i;
transpose(in_string, e_string, E_table, 64);
//Use S box for confussion
for (i = 0; i < 8; i++){
e_string[i] = (e_string[i] ^ round_key[i]) & 0x3F;
e_string[i] = s[i] [e_string[i]];
}
transpose(e_string, xor_string, P_table, 32);
}

FPGA NIOSII 工程

CSDN下载频道

DES加密:8051实现(C语言) & FPGA实现(VHDL+NIOS II)的更多相关文章

  1. DES加密解密算法C语言代码实现

    代码: #include<stdio.h> #include<string.h> #include<stdlib.h> /*-------------------- ...

  2. 兼容PHP和Java的des加密解密代码分享

    这篇文章主要介绍了兼容PHP和Java的des加密解密代码分享,适合如服务器是JAVA语言编写,客户端是PHP编写,并需要des加密解密的情况,需要的朋友可以参考下 作为一个iOS工程师来解决安卓的问 ...

  3. 各种加密解密函数(URL加密解密、sha1加密解密、des加密解密)

    原文:各种加密解密函数(URL加密解密.sha1加密解密.des加密解密) 普通hash函数如md5.sha1.base64等都是不可逆函数.虽然我们利用php可以利用这些函数写出可逆函数来.但是跨语 ...

  4. C# DES加密类,16位的加密。

    这个加密类是与java写的DES加密不同时,自己写的,最后与Java的加密相同了,解决了加密后不同的问题. 可以直接调用里面的加密和解密的方法. using System; using System. ...

  5. DES和3DES加密算法C语言实现【转】

    转自:https://blog.csdn.net/leumber/article/details/78043675 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  6. Python实现基于DES加密源码的文本加密器

    这是自行制作的一个DES文本加密工具 最终效果图: 本加密器支持UTF-8字符的加解密(包含中文),由于其中的编码方式与常用编码方式不同,加密结果与网上工具不同,但是能实现正常加解密. 最终目标: 目 ...

  7. des加密破解

    在爬取某些网站时, 登录等重要操作的返回结果是des加密后的. 如何破解 1, Python 语言采用 pyDes 作为 DES 加解密处理的包. 2,通过请求 http://tool.chacuo. ...

  8. 关于Objective-c和Java下DES加密保持一致的方式

    转载自:http://www.cnblogs.com/janken/archive/2012/04/05/2432930.html 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才 ...

  9. Android数据加密之Des加密

    前言: 端午节前有个同事咨询我有关Android DES加密的相关实现,简单的实现了一下,今天来总结一下. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes加密 ...

随机推荐

  1. 解决lxml不含etree模块导致scrapy startproject ***出错

    本文环境:win10(64) python3.6(64) 背景:之前已成功安装scrapy(1.4.0),但在命令行敲 scrapy startproject ***出错,错误提示:from ... ...

  2. ABP:在多语句事务内不允许使用 CREATE DATABASE 语句

    一.问题 使用ef codefirst开发,无法创建数据库的问题,如下提示 Server Error in '/' Application. 在多语句事务内不允许使用 CREATE DATABASE ...

  3. JavaScript表单

    JavaScript表单 这篇文章的主要目的是介绍表单相关的知识,如表单基础知识.文本框脚本相关用法.选择框脚本相关用法以及等知识.虽然在现代web开发中,很少会使用form默认行为提交表单数据,而是 ...

  4. 轻松学JVM(二)——内存模型、可见性、指令重排序

    上一篇我们介绍了JVM的基本运行流程以及内存结构,对JVM有了初步的认识,这篇文章我们将根据JVM的内存模型探索java当中变量的可见性以及不同的java指令在并发时可能发生的指令重排序的情况. 内存 ...

  5. 升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

    概述 容器,顾名思义是用来存放并容纳东西的器皿: 而容器技术伴着Docker的兴起也渐渐的映入大家的眼帘,它是一个抽象的概念,同时也是默默存在世上多年的技术,不仅能使应用程序间完全的隔离,而且还能在共 ...

  6. 社群系统ThinkSNS V4.5.29 APP更新发布,新增用户认证及系统消息

    社群系统ThinkSNS V4版本移动端APP将于7月29日更新发布,本次更新修复部分bug,最主要是增加了移动端APP的用户认证功能,以及添加了系统消息,为V4.5.29版本发布.这两个功能PC端的 ...

  7. U3D操作游戏对象

    游戏对象:所有出现在场景中的实体都是游戏对象. 一.创建游戏对象 创建游戏对象有两种方式:一是通过在unity中创建模型,而是通过脚本动态创建游戏对象.通过脚本动态创建的灵活性较高,重点也在于通过脚本 ...

  8. 常见C++面试题及基本知识点总结(一)

    [转载请注明出处]:http://www.cnblogs.com/LUO77/p/5771237.html  1. 结构体和共同体的区别. 定义: 结构体struct:把不同类型的数据组合成一个整体, ...

  9. 【每天一道算法题】时间复杂度为O(n)的排序

    有1,2,……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且一次只能交换两个数. 这个是以前看到的算法题,题目不难.但是要求比较多,排序算法中,时间 ...

  10. Leetcode Pasacl'sTriangle

    对于Vector的用法,实在是知道的太少,算法思想比较简单,核心也就一行代码,但是实现错误就显示平时代码的不熟悉. Given numRows, generate the first numRows ...