/* 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 自动判断大端 小端的更多相关文章

  1. 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 ...

  2. C/C++字节序(大端/小端)判断

    C/C++大端小端判断 说的是变量的高字节.低字节在内存地址中的排放顺序. 变量的高字节放到内存的低地址中(变量的低字节放到内存的高地址中)==>大端 变量的高字节放到内存的高地址中(变量的低字 ...

  3. (转)C系程序员面试必知必会之大端小端

      C程序员经常被问及的一道面试题是:什么是大端/小端,怎么样判断是大端/小端?大端小端问题对于嵌入式程序员绝对不会陌生(否则,别告诉我你是搞嵌入式的),它与CPU体系结构有关.比如常见的X86处理器 ...

  4. 不同生产商的CPU以及大端/小端对齐

    ● 不同生产商的CPU以及大端/小端对齐 ※ ARM.AMD.Atom和intel之间的关系   intel公司和AMD公司生产的是相同的x86架构的CPU,这种CPU属于CISC(Complex I ...

  5. C++查看大端小端模式

    在学习计算机组成原理的时候,看到大端小端模式,便想实验一下,首先介绍一下 C 中的union,这个平时用得少,估计在单片机这种可能会运用,在平时写代码的时候几乎是用不着union的. union:联合 ...

  6. java的大端小端和c#如何对应

    当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...

  7. linux kernel如何处理大端小端字节序

    (转)http://blog.csdn.net/skyflying2012/article/details/43771179 最近在做将kernel由小端处理器(arm)向大端处理器(ppc)的移植的 ...

  8. 大端小端(Big- Endian和Little-Endian)[转]

    原文出处: 字节序(Endian),大端(Big-Endian),小端(Little-Endian)  http://www.cppblog.com/tx7do/archive/2009/01/06/ ...

  9. 大端小端转换,le32_to_cpu 和cpu_to_le32

    字节序 http://oss.org.cn/kernel-book/ldd3/ch11s04.html 小心不要假设字节序. PC 存储多字节值是低字节为先(小端为先, 因此是小端), 一些高级的平台 ...

随机推荐

  1. shiro:10个过滤器;10个jsp标签;5个@注解

    10个过滤器 过滤器简称 对应的java类 anon org.apache.shiro.web.filter.authc.AnonymousFilter authc org.apache.shiro. ...

  2. 为eclipse EE(汉化版) 配置Tomcat服务器

    为eclipse EE(汉化版) 配置Tomcat服务器   很多小朋友在初次使用eclipse进行web开发的时候,很是蒙蔽.以前都是文本编辑器写好,做好目录结构,往tomcat下一扔,重启,搞定. ...

  3. 团队项目:"Jarvis For Chat"

    "Jarvis For Chat"项目简介 项目详情信息已经在上一篇博客中详细给出,详请查看博客 团队成员 姓名 学号 张扬(队长) 031602345 苏韫月 031602631 ...

  4. lcx端口转发 linux版

    一.端口转发使用 1.攻击机上执行以下命令 ./lcx -p1 -p2 -m 在本地监听3389端口,并将发送到本机3389端口的数据传递到本机2222端口 2.跳板机上执行以下命令 ./lcx -h ...

  5. avr 烧录失败

    用Atmel studio 6.0 配置mkII烧录器 使用上位机bat程序烧录 提示错误:firmware is old... 1参考(关于FUSe setting) http://www.cnbl ...

  6. css实现加载中的效果

    那天闲着,学习了一下样式效果,自己实现了一个简单的加载中的效果 废话不多说,开始吧!! 一.实现一个圆环       要实现圆环,首先我们需要知道盒模型里面border的本质,先来看一个效果吧 从上面 ...

  7. Objective C----手动管理内存和自动管理内存

    对象的引用计数(Reference Counting) 正常情况下,当一段代码需要访问某个对象时,该对象的引用的计数加1:当这段代码不再访问该对象时,该对象的引用计数减1,表示这段代码不再访问该对象: ...

  8. linux uname和dpkg命令

    uname -a:查看系统一些参数 dpkg -i:安装下载好的.deb包裹

  9. css 问题

    问题1:使得在div中的图片自适应于Div的大小 图片放在DIV中是为了更好地管理,那么如果图片不能自适应与div的大小,则此事的初衷就会变质. 怎样自适应呢,有一个很简单的办法: img{ widt ...

  10. [剑指offer]09用两个栈实现队列插入和删除操作,C++实现

    原创博文,转载请注明出处! # 本文为牛客网<剑指offer>刷题笔记 1.题目 # 用两个栈实现队列的插入和删除操作 2.思路 栈服从先入后出的原则处理数据,队列服从先入先出的原则处理数 ...