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 存储多字节值是低字节为先(小端为先, 因此是小端), 一些高级的平台 ...
随机推荐
- RabbitMQ其他(八)
1 RabbitMQ消息队列的小伙伴: ProtoBuf(Google Protocol Buffer) 什么是ProtoBuf? 一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序 ...
- CF911D
题解: 简单的奇偶判断 代码: #include<bits/stdc++.h> using namespace std; ; int n,a[N],ans,m,p,q; int main( ...
- JQuery iframe
子页面获取父页面的元素 function colisetapTJ() { var tapid = $('div:contains("添加档案报送"):last', window.p ...
- openoffice在连接时有错误,无法连接上
openoffice在连接时有错误,无法连接上 报如下错误: java.net.ConnectException: connection failed: socket,host=localhost,p ...
- CS231n课程笔记翻译3:线性分类笔记
译者注:本文智能单元首发,译自斯坦福CS231n课程笔记Linear Classification Note,课程教师Andrej Karpathy授权翻译.本篇教程由杜客翻译完成,巩子嘉和堃堃进行校 ...
- python 多维list声明时的小问题
a=[[]]*3 a Out[18]: [[], [], []] a[0].append(1) a Out[20]: [[1], [1], [1]] b=[[] for _ in range(3)] ...
- xcode好玩的条件断点设置. 可以真人发声。
哈哈.设置个条件断点. 然后 Logmessage or speak message 挺有意思. 一听就知道是哪个断点触发了.
- sift特征简述
参考文献:http://blog.csdn.net/abcjennifer/article/details/7639681 分为几个步骤: 1. 构建尺度空间 2. LoG近似DoG找到关键点< ...
- learn go function callback
package main // 参考文档: // https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/06.7.md im ...
- base64 和 Blob 相互转换
Base64 to Blob function dataURLtoBlob(dataurl) { var arr = dataurl.split(','), mime = arr[0].match(/ ...