CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。

CRC算法参数模型解释:
NAME:参数模型名称。
WIDTH:宽度,即CRC比特数。
POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的"1",即完整的生成项是0x104C11DB7。
INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。
REFIN:待测数据的每个字节是否按位反转,True或False。
REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。
XOROUT:计算结果与此参数异或后得到最终的CRC值。

常见CRC参数模型如下:

CRC算法名称

多项式公式

宽度

多项式

初始值

结果异或值

输入反转

输出反转

CRC-4/ITU

x4 + x + 1

4

03

00

00

true

true

CRC-5/EPC

x5 + x3 + 1

5

09

09

00

false

false

CRC-5/ITU

x5 + x4 + x2 + 1

5

15

00

00

true

true

CRC-5/USB

x5 + x2 + 1

5

05

1F

1F

true

true

CRC-6/ITU

x6 + x + 1

6

03

00

00

true

true

CRC-7/MMC

x7 + x3 + 1

7

09

00

00

false

false

CRC-8

x8 + x2 + x + 1

8

07

00

00

false

false

CRC-8/ITU

x8 + x2 + x + 1

8

07

00

55

false

false

CRC-8/ROHC

x8 + x2 + x + 1

8

07

FF

00

true

true

CRC-8/MAXIM

x8 + x5 + x4 + 1

8

31

00

00

true

true

CRC-16/IBM

x16 + x15 + x2 + 1

16

8005

0000

0000

true

true

CRC-16/MAXIM

x16 + x15 + x2 + 1

16

8005

0000

FFFF

true

true

CRC-16/USB

x16 + x15 + x2 + 1

16

8005

FFFF

FFFF

true

true

CRC-16/MODBUS

x16 + x15 + x2 + 1

16

8005

FFFF

0000

true

true

CRC-16/CCITT

x16 + x12 + x5 + 1

16

1021

0000

0000

true

true

CRC-16/CCITT-FALSE

x16 + x12 + x5 + 1

16

1021

FFFF

0000

false

false

CRC-16/X25

x16 + x12 + x5 + 1

16

1021

FFFF

FFFF

true

true

CRC-16/XMODEM

x16 + x12 + x5 + 1

16

1021

0000

0000

false

false

CRC-16/DNP

x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1

16

3D65

0000

FFFF

true

true

CRC-32

x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

32

04C11DB7

FFFFFFFF

FFFFFFFF

true

true

CRC-32/MPEG-2

x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1

32

04C11DB7

FFFFFFFF

00000000

false

false

uint8_t crc4_itu(uint8_t *data, uint_len length);

uint8_t crc5_epc(uint8_t *data, uint_len length);

uint8_t crc5_itu(uint8_t *data, uint_len length);

uint8_t crc5_usb(uint8_t *data, uint_len length);

uint8_t crc6_itu(uint8_t *data, uint_len length);

uint8_t crc7_mmc(uint8_t *data, uint_len length);

uint8_t crc8(uint8_t *data, uint_len length);

uint8_t crc8_itu(uint8_t *data, uint_len length);

uint8_t crc8_rohc(uint8_t *data, uint_len length);

uint8_t crc8_maxim(uint8_t *data, uint_len length);//DS18B20

uint16_t crc16_ibm(uint8_t *data, uint_len length);

uint16_t crc16_maxim(uint8_t *data, uint_len length);

uint16_t crc16_usb(uint8_t *data, uint_len length);

uint16_t crc16_modbus(uint8_t *data, uint_len length);

uint16_t crc16_ccitt(uint8_t *data, uint_len length);

uint16_t crc16_ccitt_false(uint8_t *data, uint_len length);

uint16_t crc16_x25(uint8_t *data, uint_len length);

uint16_t crc16_xmodem(uint8_t *data, uint_len length);

uint16_t crc16_dnp(uint8_t *data, uint_len length);

uint32_t crc32(uint8_t *data, uint_len length);

uint32_t crc32_mpeg_2(uint8_t *data, uint_len length);/******************************************************************************

* Name:    CRC-4/ITU           x4+x+1

* Poly:    0x03

* Init:    0x00

* Refin:   True

* Refout:  True

* Xorout:  0x00

* Note:

*****************************************************************************/

uint8_t crc4_itu(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;                // Initial value

while(length--)

{

crc ^= *data++;                 // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x0C;// 0x0C = (reverse 0x03)>>(8-4)

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-5/EPC           x5+x3+1

* Poly:    0x09

* Init:    0x09

* Refin:   False

* Refout:  False

* Xorout:  0x00

* Note:

*****************************************************************************/

uint8_t crc5_epc(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0x48;        // Initial value: 0x48 = 0x09<<(8-5)

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if ( crc & 0x80 )

crc = (crc << 1) ^ 0x48;        // 0x48 = 0x09<<(8-5)

else

crc <<= 1;

}

}

return crc >> 3;}

/******************************************************************************

* Name:    CRC-5/ITU           x5+x4+x2+1

* Poly:    0x15

* Init:    0x00

* Refin:   True

* Refout:  True

* Xorout:  0x00

* Note:

*****************************************************************************/

uint8_t crc5_itu(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;                // Initial value

while(length--)

{

crc ^= *data++;                 // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x15;// 0x15 = (reverse 0x15)>>(8-5)

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-5/USB           x5+x2+1

* Poly:    0x05

* Init:    0x1F

* Refin:   True

* Refout:  True

* Xorout:  0x1F

* Note:

*****************************************************************************/

uint8_t crc5_usb(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0x1F;                // Initial value

while(length--)

{

crc ^= *data++;                 // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x14;// 0x14 = (reverse 0x05)>>(8-5)

else

crc = (crc >> 1);

}

}

return crc ^ 0x1F;}

/******************************************************************************

* Name:    CRC-6/ITU           x6+x+1

* Poly:    0x03

* Init:    0x00

* Refin:   True

* Refout:  True

* Xorout:  0x00

* Note:

*****************************************************************************/

uint8_t crc6_itu(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;         // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x30;// 0x30 = (reverse 0x03)>>(8-6)

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-7/MMC           x7+x3+1

* Poly:    0x09

* Init:    0x00

* Refin:   False

* Refout:  False

* Xorout:  0x00

* Use:     MultiMediaCard,SD,ect.

*****************************************************************************/

uint8_t crc7_mmc(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;        // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if ( crc & 0x80 )

crc = (crc << 1) ^ 0x12;        // 0x12 = 0x09<<(8-7)

else

crc <<= 1;

}

}

return crc >> 1;}

/******************************************************************************

* Name:    CRC-8               x8+x2+x+1

* Poly:    0x07

* Init:    0x00

* Refin:   False

* Refout:  False

* Xorout:  0x00

* Note:

*****************************************************************************/

uint8_t crc8(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;        // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if ( crc & 0x80 )

crc = (crc << 1) ^ 0x07;

else

crc <<= 1;

}

}

return crc;}

/******************************************************************************

* Name:    CRC-8/ITU           x8+x2+x+1

* Poly:    0x07

* Init:    0x00

* Refin:   False

* Refout:  False

* Xorout:  0x55

* Alias:   CRC-8/ATM

*****************************************************************************/

uint8_t crc8_itu(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;        // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if ( crc & 0x80 )

crc = (crc << 1) ^ 0x07;

else

crc <<= 1;

}

}

return crc ^ 0x55;}

/******************************************************************************

* Name:    CRC-8/ROHC          x8+x2+x+1

* Poly:    0x07

* Init:    0xFF

* Refin:   True

* Refout:  True

* Xorout:  0x00

* Note:

*****************************************************************************/

uint8_t crc8_rohc(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0xFF;         // Initial value

while(length--)

{

crc ^= *data++;            // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xE0;        // 0xE0 = reverse 0x07

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-8/MAXIM         x8+x5+x4+1

* Poly:    0x31

* Init:    0x00

* Refin:   True

* Refout:  True

* Xorout:  0x00

* Alias:   DOW-CRC,CRC-8/IBUTTON

* Use:     Maxim(Dallas)'s some devices,e.g. DS18B20

*****************************************************************************/

uint8_t crc8_maxim(uint8_t *data, uint_len length){

uint8_t i;

uint8_t crc = 0;         // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x8C;        // 0x8C = reverse 0x31

else

crc >>= 1;

}

}

return crc;}

/******************************************************************************

* Name:    CRC-16/IBM          x16+x15+x2+1

* Poly:    0x8005

* Init:    0x0000

* Refin:   True

* Refout:  True

* Xorout:  0x0000

* Alias:   CRC-16,CRC-16/ARC,CRC-16/LHA

*****************************************************************************/

uint16_t crc16_ibm(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0;        // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xA001;        // 0xA001 = reverse 0x8005

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-16/MAXIM        x16+x15+x2+1

* Poly:    0x8005

* Init:    0x0000

* Refin:   True

* Refout:  True

* Xorout:  0xFFFF

* Note:

*****************************************************************************/

uint16_t crc16_maxim(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0;        // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xA001;        // 0xA001 = reverse 0x8005

else

crc = (crc >> 1);

}

}

return ~crc;    // crc^0xffff}

/******************************************************************************

* Name:    CRC-16/USB          x16+x15+x2+1

* Poly:    0x8005

* Init:    0xFFFF

* Refin:   True

* Refout:  True

* Xorout:  0xFFFF

* Note:

*****************************************************************************/

uint16_t crc16_usb(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0xffff;        // Initial value

while(length--)

{

crc ^= *data++;            // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xA001;        // 0xA001 = reverse 0x8005

else

crc = (crc >> 1);

}

}

return ~crc;    // crc^0xffff}

/******************************************************************************

* Name:    CRC-16/MODBUS       x16+x15+x2+1

* Poly:    0x8005

* Init:    0xFFFF

* Refin:   True

* Refout:  True

* Xorout:  0x0000

* Note:

*****************************************************************************/

uint16_t crc16_modbus(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0xffff;        // Initial value

while(length--)

{

crc ^= *data++;            // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xA001;        // 0xA001 = reverse 0x8005

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-16/CCITT        x16+x12+x5+1

* Poly:    0x1021

* Init:    0x0000

* Refin:   True

* Refout:  True

* Xorout:  0x0000

* Alias:   CRC-CCITT,CRC-16/CCITT-TRUE,CRC-16/KERMIT

*****************************************************************************/

uint16_t crc16_ccitt(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0;        // Initial value

while(length--)

{

crc ^= *data++;        // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x8408;        // 0x8408 = reverse 0x1021

else

crc = (crc >> 1);

}

}

return crc;}

/******************************************************************************

* Name:    CRC-16/CCITT-FALSE   x16+x12+x5+1

* Poly:    0x1021

* Init:    0xFFFF

* Refin:   False

* Refout:  False

* Xorout:  0x0000

* Note:

*****************************************************************************/

uint16_t crc16_ccitt_false(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0xffff;        //Initial value

while(length--)

{

crc ^= (uint16_t)(*data++) << 8; // crc ^= (uint6_t)(*data)<<8; data++;

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

{

if ( crc & 0x8000 )

crc = (crc << 1) ^ 0x1021;

else

crc <<= 1;

}

}

return crc;}

/******************************************************************************

* Name:    CRC-16/X25          x16+x12+x5+1

* Poly:    0x1021

* Init:    0xFFFF

* Refin:   True

* Refout:  True

* Xorout:  0XFFFF

* Note:

*****************************************************************************/

uint16_t crc16_x25(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0xffff;        // Initial value

while(length--)

{

crc ^= *data++;            // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0x8408;        // 0x8408 = reverse 0x1021

else

crc = (crc >> 1);

}

}

return ~crc;                // crc^Xorout}

/******************************************************************************

* Name:    CRC-16/XMODEM       x16+x12+x5+1

* Poly:    0x1021

* Init:    0x0000

* Refin:   False

* Refout:  False

* Xorout:  0x0000

* Alias:   CRC-16/ZMODEM,CRC-16/ACORN

*****************************************************************************/

uint16_t crc16_xmodem(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0;            // Initial value

while(length--)

{

crc ^= (uint16_t)(*data++) << 8; // crc ^= (uint16_t)(*data)<<8; data++;

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

{

if ( crc & 0x8000 )

crc = (crc << 1) ^ 0x1021;

else

crc <<= 1;

}

}

return crc;}

/******************************************************************************

* Name:    CRC-16/DNP          x16+x13+x12+x11+x10+x8+x6+x5+x2+1

* Poly:    0x3D65

* Init:    0x0000

* Refin:   True

* Refout:  True

* Xorout:  0xFFFF

* Use:     M-Bus,ect.

*****************************************************************************/

uint16_t crc16_dnp(uint8_t *data, uint_len length){

uint8_t i;

uint16_t crc = 0;            // Initial value

while(length--)

{

crc ^= *data++;            // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xA6BC;        // 0xA6BC = reverse 0x3D65

else

crc = (crc >> 1);

}

}

return ~crc;                // crc^Xorout}

/******************************************************************************

* Name:    CRC-32  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

* Poly:    0x4C11DB7

* Init:    0xFFFFFFF

* Refin:   True

* Refout:  True

* Xorout:  0xFFFFFFF

* Alias:   CRC_32/ADCCP

* Use:     WinRAR,ect.

*****************************************************************************/

uint32_t crc32(uint8_t *data, uint_len length){

uint8_t i;

uint32_t crc = 0xffffffff;        // Initial value

while(length--)

{

crc ^= *data++;                // crc ^= *data; data++;

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

{

if (crc & 1)

crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7

else

crc = (crc >> 1);

}

}

return ~crc;}

/******************************************************************************

* Name:    CRC-32/MPEG-2  x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

* Poly:    0x4C11DB7

* Init:    0xFFFFFFF

* Refin:   False

* Refout:  False

* Xorout:  0x0000000

* Note:

*****************************************************************************/

uint32_t crc32_mpeg_2(uint8_t *data, uint_len length){

uint8_t i;

uint32_t crc = 0xffffffff;  // Initial value

while(length--)

{

crc ^= (uint32_t)(*data++) << 24;// crc ^=(uint32_t)(*data)<<24; data++;

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

{

if ( crc & 0x80000000 )

crc = (crc << 1) ^ 0x04C11DB7;

else

crc <<= 1;

}

}

return crc;}

CRC校验(循环冗余校验)小知识相关推荐

  1. CRC(循环冗余校验)查表算法的代码实现

    CRC(循环冗余校验)查表算法的代码实现 前言 准备工作 查表算法的由来 查表算法的基本原理 模二减法(异或运算)的性质 对直接计算法进行分析 基本原理的推广 查表算法的代码实现 测试用例 正式编码 ...

  2. CRC(循环冗余校验)离线计算

    1.前言 参考CRC在线计算方式.CRC(循环冗余校验)在线计算_ip33.com 开发matlab 版本的CRC离线计算,针对有些离线电脑可以很方便使用. 代码开源,方便自定义使用. 2.开发工具 ...

  3. 【基础知识】CRC(循环冗余校验)直接计算和查表法

    CRC概述 校验 校验是什么,个人理解就是经过一个算法,使用大量数据(几MB的数据)生成较小长度的一串信息(如16Bit),并切要做到 原数据不同时,生成的信息大概率不同(不是加密算法不考虑刻意造数据 ...

  4. 【科普向】谁都能看懂的CRC(循环冗余校验)原理

    CRC原理 简介 CRC基本原理 模二运算 二进制系数多项式 CRC算法 示例 CRC算法的数学描述 常用CRC版本 CRC算法的编程实现 简介 循环冗余校验(Cyclic Redundancy Ch ...

  5. CRC(循环冗余校验)

    在数据传输过程中,无论传输系统的设计再怎么完美,差错总会存在,这种差错可能会导致在链路上传输的一个或者多个帧被破坏(出现比特差错,0变为1,或者1变为0),从而接受方接收到错误的数据.为尽量提高接受方 ...

  6. 关于modbus rtu协议的CRC(循环冗余校验)在线计算

    上位机须按照MODBUS协议的命令格式发送数据(包括计算的CRC值),从机才能正确辨识数据.若无CRC值,从机将返回含有错误号的应答包,不会得到正确结果.标准的做法,发送前计算CRC值并一起发送,接收 ...

  7. c语言累加和校验_循环冗余校验(CRC)算法入门

    http://blog.csdn.net/liyuanbhu/article/details/7882789 前言 CRC校验(循环冗余校验)是数据通讯中最常采用的校验方式.在嵌入式软件开发中,经常要 ...

  8. 十六、基于FPGA的CRC校验设计实现

    1,CRC校验 循环冗余校验(Cyclic Redundancy Check, CRC)是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检测或校验数据传输或者保 ...

  9. 一文详解循环冗余校验校验算法(CRC校验)及C语言代码的实现 ---- 以CRC-16/MODBUS为例讲解

    一.概述 现在的产品开发过程中,无论是数据的储存还是传输,都需要确保数据的准确性,所以就需要在数据帧后面附加一串校验码,方便接收方使用校验码校验接收到的数据是否是正确的. 常用的校验方式有奇偶校验.异 ...

  10. [2021.07.25更新]循环冗余校验(CRC)的MATLAB实现

    欢迎同步关注公众号[逆向通信猿] CRC校验(循环冗余校验) 在计算CRC校验的时候,发现一个网站如下 http://www.ip33.com/crc.html 于是,想自己动手实现该网站计算CRC校 ...

最新文章

  1. B-监狱逃脱(BFS)
  2. 美国科技界高度关注中国科技创新进展
  3. 建造者模式(工厂模式6)
  4. mysql是开放源代码_但这可能是很因难的,因为MySQL是开放源代码的,所以任何人...
  5. 他开发了 redux,昨晚字节一面却挂了?
  6. 百面机器学习—11.集成学习(GBDT、XGBoost)面试问题总结
  7. Latex: 表格内换行
  8. 对多媒体框架的几点看法
  9. 计算机没有休眠,没有休眠选项,电脑没有休眠选项
  10. 使用pandas sns绘图
  11. iphone导出视频 无法连接到设备_iPhone内存不足?深度清理方法了解一下
  12. 如何用标题博得观众眼球
  13. React Native实践之携程Moles框架
  14. 哪个软件可以识别手写字?推荐好用的办法
  15. 惠普HP DeskJet Ink Advantage Ultra 4729 驱动
  16. 为什么计算机编程全用英语,为什么所有编程都是英文的?为什么不能中文程序?...
  17. 回调函数到底有什么好处
  18. 计算机科学与技术论文提纲,计算机科学与技术专业论文提纲格式模板 计算机科学与技术专业论文提纲怎样写...
  19. [Vue warn]: Failed to resolve directive: focus
  20. 台式计算机的美图,为什么我在台式电脑上看图片,图片色彩很饱和很鲜艳,而笔记本上看的图片有点暗淡呢...

热门文章

  1. html 在线测试 鱼缸,研究员试图用AR鱼缸欺骗鱼的感官系统,结果反被鱼识破
  2. IDEA内无法进行复制粘贴
  3. 订单可视化(智能制造、流程再造、企业信息化) 第四篇 技术方案的制定
  4. matlab生成的数值为inf,计算值时为Nan / inf
  5. html修改文本框样式,HTML实用文本框样式
  6. 注意啦!使用“流量卡”别图便宜,小心被监控!
  7. 从一位前阿里P7被裁员,聊技术人的第二职业!
  8. 北京 Beijing
  9. 修改Win10右键菜单
  10. c语言解除键盘锁定,笔记本电脑解除键盘锁定的常见方法