CRC 自动判断大端 小端
/* aos_crc64.c -- compute CRC-64
* Copyright (C) 2013 Mark Adler
* Version 1.4 16 Dec 2013 Mark Adler
*/ /*
This software is provided 'as-is', without any express or implied
warranty. In no event will the author be held liable for any damages
arising from the use of this software. Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. Mark Adler
madler@alumni.caltech.edu
*/ /* Compute CRC-64 in the manner of xz, using the ECMA-182 polynomial,
bit-reversed, with one's complement pre and post processing. Provide a
means to combine separately computed CRC-64's. */ /* Version history:
1.0 13 Dec 2013 First version
1.1 13 Dec 2013 Fix comments in test code
1.2 14 Dec 2013 Determine endianess at run time
1.3 15 Dec 2013 Add eight-byte processing for big endian as well
Make use of the pthread library optional
1.4 16 Dec 2013 Make once variable volatile for limited thread protection
*/ #include "aos_crc64.h" /* 64-bit CRC polynomial with these coefficients, but reversed:
64, 62, 57, 55, 54, 53, 52, 47, 46, 45, 40, 39, 38, 37, 35, 33, 32,
31, 29, 27, 24, 23, 22, 21, 19, 17, 13, 12, 10, 9, 7, 4, 1, 0 */
#define POLY UINT64_C(0xc96c5795d7870f42) /* Tables for CRC calculation -- filled in by initialization functions that are
called once. These could be replaced by constant tables generated in the
same way. There are two tables, one for each endianess. Since these are
static, i.e. local, one should be compiled out of existence if the compiler
can evaluate the endianess check in crc64() at compile time. */
static uint64_t crc64_little_table[][];
static uint64_t crc64_big_table[][]; /* Fill in the CRC-64 constants table. */
static void crc64_init(uint64_t table[][])
{
unsigned n, k;
uint64_t crc; /* generate CRC-64's for all single byte sequences */
for (n = ; n < ; n++) {
crc = n;
for (k = ; k < ; k++)
crc = crc & ? POLY ^ (crc >> ) : crc >> ;
table[][n] = crc;
} /* generate CRC-64's for those followed by 1 to 7 zeros */
for (n = ; n < ; n++) {
crc = table[][n];
for (k = ; k < ; k++) {
crc = table[][crc & 0xff] ^ (crc >> );
table[k][n] = crc;
}
}
} /* This function is called once to initialize the CRC-64 table for use on a
little-endian architecture. */
static void crc64_little_init(void)
{
crc64_init(crc64_little_table);
} /* Reverse the bytes in a 64-bit word. */
static APR_INLINE uint64_t rev8(uint64_t a)
{
uint64_t m; m = UINT64_C(0xff00ff00ff00ff);
a = ((a >> ) & m) | (a & m) << ;
m = UINT64_C(0xffff0000ffff);
a = ((a >> ) & m) | (a & m) << ;
return a >> | a << ;
} /* This function is called once to initialize the CRC-64 table for use on a
big-endian architecture. */
static void crc64_big_init(void)
{
unsigned k, n; crc64_init(crc64_big_table);
for (k = ; k < ; k++)
for (n = ; n < ; n++)
crc64_big_table[k][n] = rev8(crc64_big_table[k][n]);
} /* Run the init() function exactly once. If pthread.h is not included, then
this macro will use a simple static state variable for the purpose, which is
not thread-safe. The init function must be of the type void init(void). */
#ifdef PTHREAD_ONCE_INIT
# define ONCE(init) \
do { \
static pthread_once_t once = PTHREAD_ONCE_INIT; \
pthread_once(&once, init); \
} while ()
#else
# define ONCE(init) \
do { \
static volatile int once = ; \
if (once) { \
if (once++ == ) { \
init(); \
once = ; \
} \
else \
while (once) \
; \
} \
} while ()
#endif /* Calculate a CRC-64 eight bytes at a time on a little-endian architecture. */
static APR_INLINE uint64_t crc64_little(uint64_t crc, void *buf, size_t len)
{
unsigned char *next = buf; ONCE(crc64_little_init);
crc = ~crc;
while (len && ((uintptr_t)next & ) != ) {
crc = crc64_little_table[][(crc ^ *next++) & 0xff] ^ (crc >> );
len--;
}
while (len >= ) {
crc ^= *(uint64_t *)next;
crc = crc64_little_table[][crc & 0xff] ^
crc64_little_table[][(crc >> ) & 0xff] ^
crc64_little_table[][(crc >> ) & 0xff] ^
crc64_little_table[][(crc >> ) & 0xff] ^
crc64_little_table[][(crc >> ) & 0xff] ^
crc64_little_table[][(crc >> ) & 0xff] ^
crc64_little_table[][(crc >> ) & 0xff] ^
crc64_little_table[][crc >> ];
next += ;
len -= ;
}
while (len) {
crc = crc64_little_table[][(crc ^ *next++) & 0xff] ^ (crc >> );
len--;
}
return ~crc;
} /* Calculate a CRC-64 eight bytes at a time on a big-endian architecture. */
static APR_INLINE uint64_t crc64_big(uint64_t crc, void *buf, size_t len)
{
unsigned char *next = buf; ONCE(crc64_big_init);
crc = ~rev8(crc);
while (len && ((uintptr_t)next & ) != ) {
crc = crc64_big_table[][(crc >> ) ^ *next++] ^ (crc << );
len--;
}
while (len >= ) {
crc ^= *(uint64_t *)next;
crc = crc64_big_table[][crc & 0xff] ^
crc64_big_table[][(crc >> ) & 0xff] ^
crc64_big_table[][(crc >> ) & 0xff] ^
crc64_big_table[][(crc >> ) & 0xff] ^
crc64_big_table[][(crc >> ) & 0xff] ^
crc64_big_table[][(crc >> ) & 0xff] ^
crc64_big_table[][(crc >> ) & 0xff] ^
crc64_big_table[][crc >> ];
next += ;
len -= ;
}
while (len) {
crc = crc64_big_table[][(crc >> ) ^ *next++] ^ (crc << );
len--;
}
return ~rev8(crc);
} /* Return the CRC-64 of buf[0..len-1] with initial crc, processing eight bytes
at a time. This selects one of two routines depending on the endianess of
the architecture. A good optimizing compiler will determine the endianess
at compile time if it can, and get rid of the unused code and table. If the
endianess can be changed at run time, then this code will handle that as
well, initializing and using two tables, if called upon to do so. */
uint64_t aos_crc64(uint64_t crc, void *buf, size_t len)
{
uint64_t n = ; return *(char *)&n ? crc64_little(crc, buf, len) :
crc64_big(crc, buf, len);
} #define GF2_DIM 64 /* dimension of GF(2) vectors (length of CRC) */ static uint64_t gf2_matrix_times(uint64_t *mat, uint64_t vec)
{
uint64_t sum; sum = ;
while (vec) {
if (vec & )
sum ^= *mat;
vec >>= ;
mat++;
}
return sum;
} static void gf2_matrix_square(uint64_t *square, uint64_t *mat)
{
unsigned n; for (n = ; n < GF2_DIM; n++)
square[n] = gf2_matrix_times(mat, mat[n]);
} /* Return the CRC-64 of two sequential blocks, where crc1 is the CRC-64 of the
first block, crc2 is the CRC-64 of the second block, and len2 is the length
of the second block. */
uint64_t aos_crc64_combine(uint64_t crc1, uint64_t crc2, uintmax_t len2)
{
unsigned n;
uint64_t row;
uint64_t even[GF2_DIM]; /* even-power-of-two zeros operator */
uint64_t odd[GF2_DIM]; /* odd-power-of-two zeros operator */ /* degenerate case */
if (len2 == )
return crc1; /* put operator for one zero bit in odd */
odd[] = POLY; /* CRC-64 polynomial */
row = ;
for (n = ; n < GF2_DIM; n++) {
odd[n] = row;
row <<= ;
} /* put operator for two zero bits in even */
gf2_matrix_square(even, odd); /* put operator for four zero bits in odd */
gf2_matrix_square(odd, even); /* apply len2 zeros to crc1 (first square will put the operator for one
zero byte, eight zero bits, in even) */
do {
/* apply zeros operator for this bit of len2 */
gf2_matrix_square(even, odd);
if (len2 & )
crc1 = gf2_matrix_times(even, crc1);
len2 >>= ; /* if no more bits set, then done */
if (len2 == )
break; /* another iteration of the loop with odd and even swapped */
gf2_matrix_square(odd, even);
if (len2 & )
crc1 = gf2_matrix_times(odd, crc1);
len2 >>= ; /* if no more bits set, then done */
} while (len2 != ); /* return combined crc */
crc1 ^= crc2;
return crc1;
}
CRC 自动判断大端 小端的更多相关文章
- c# 16进制大端小端解析长度
//前两个字节为长度的解析string hexstr = "00 13 59 02 80 00 E7 00 80 00 E9 00 80 00 EA 00 80 00 EB 00 80&qu ...
- C/C++字节序(大端/小端)判断
C/C++大端小端判断 说的是变量的高字节.低字节在内存地址中的排放顺序. 变量的高字节放到内存的低地址中(变量的低字节放到内存的高地址中)==>大端 变量的高字节放到内存的高地址中(变量的低字 ...
- (转)C系程序员面试必知必会之大端小端
C程序员经常被问及的一道面试题是:什么是大端/小端,怎么样判断是大端/小端?大端小端问题对于嵌入式程序员绝对不会陌生(否则,别告诉我你是搞嵌入式的),它与CPU体系结构有关.比如常见的X86处理器 ...
- 不同生产商的CPU以及大端/小端对齐
● 不同生产商的CPU以及大端/小端对齐 ※ ARM.AMD.Atom和intel之间的关系 intel公司和AMD公司生产的是相同的x86架构的CPU,这种CPU属于CISC(Complex I ...
- C++查看大端小端模式
在学习计算机组成原理的时候,看到大端小端模式,便想实验一下,首先介绍一下 C 中的union,这个平时用得少,估计在单片机这种可能会运用,在平时写代码的时候几乎是用不着union的. union:联合 ...
- java的大端小端和c#如何对应
当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...
- linux kernel如何处理大端小端字节序
(转)http://blog.csdn.net/skyflying2012/article/details/43771179 最近在做将kernel由小端处理器(arm)向大端处理器(ppc)的移植的 ...
- 大端小端(Big- Endian和Little-Endian)[转]
原文出处: 字节序(Endian),大端(Big-Endian),小端(Little-Endian) http://www.cppblog.com/tx7do/archive/2009/01/06/ ...
- 大端小端转换,le32_to_cpu 和cpu_to_le32
字节序 http://oss.org.cn/kernel-book/ldd3/ch11s04.html 小心不要假设字节序. PC 存储多字节值是低字节为先(小端为先, 因此是小端), 一些高级的平台 ...
随机推荐
- 安装使用babel-polyfill。让IE支持es6
安装 npm install --save-dev babel-polyfill 使用 在你的代码头部加载babel-polyfill,注意一定要在你的代码开始前,第一个js文件的顶部.如果是vue在 ...
- 011PHP基础知识——运算符(四)
<?php /** * 连接运算符: . 连接2个参数生成新的字符串: */ /*$str="中国"; $bbs="bbs.blog.com"; $new ...
- 使用Unity创建塔防游戏(Part3)—— 项目总结
之前我们完成了使用Unity创建塔防游戏这个小项目,在这篇文章里,我们对项目中学习到的知识进行一次总结. Part1的地址:http://www.cnblogs.com/lcxBlog/p/60759 ...
- Spring实例化bean的几种方式
一,通过constructor实例化bean Spring可以实例化各种类型的类,不要求必须是JavaBean类型的类.在XML中配置类如下: <bean id="exampleBea ...
- LeetCode OJ:Reverse Bits(旋转bit位)
Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in ...
- set类型以及其操作
sets类型 sets类型以及操作Set是无序集合,它是string类型的无序集合.set是通过hash table实现的,添加.删除和查找的复杂度都是0(1).对集合我们可以取并集.交集.差集.通过 ...
- LINUX中的DNS服务---DNS正向、反向和双向解析
一.DNS的正向解析 也就是域名解析为IP地址进行访问! 1)vim /etc/named.conf ----> 删除forwarders所在行 2)vim /etc/named.rf ...
- ionic安装插件常用命令
常见插件查找网站: http://ngcordova.com/docs/plugins http://cordova.apache.org/plugins/ $ ionic plugin list / ...
- 《Tomcat内核设计剖析》京东评论过百
到京东看了下<Tomcat内核设计剖析>评论都一百多了,上个月也第二次印刷了,这里看下好评.中评和差评. 好评: 中评 对于中评,请看 为什么<写Tomcat内核设计剖析>,就 ...
- C语言变量、函数的作用域及变量的存储方式
一.变量的作用域和存储方式 在C语言中每个变量都有两种基本属性:数据类型.数据的存储类别. 数据类型很多人都已熟知,例如:字符型(char).整型(int).浮点型(float)等等.存储类别是指数据 ...