/* 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. Python中的map和reduce函数简介

    ①从参数方面来讲: map()函数: map()包含两个参数,第一个是参数是一个函数,第二个是序列(列表或元组).其中,函数(即map的第一个参数位置的函数)可以接收一个或多个参数. reduce() ...

  2. Java 进阶7 并发优化 1 并行程序的设计模式

       本章重点介绍的是基于 Java并行程序开发以及优化的方法,对于多核的 CPU,传统的串行程序已经很好的发回了 CPU性能,此时如果想进一步提高程序的性能,就应该使用多线程并行的方式挖掘 CPU的 ...

  3. 用U盘安装ubuntu

    用U盘安装操作系统,并不鲜见,对于Windows,可以用大白菜安装XP.Win7等,本质上是在U盘上安装一个小型的windows(WinPE),然后利用ghost一键还原技术,把U盘中的XP.gho( ...

  4. Prism 4 文档 ---第5章 实现MVVM模式

        MVVM模式有助于清楚的区分应用程序界面的业务层和展现层.保持一个清晰的应用程序逻辑和UI分离有助于处理开发和设计过程中大量的问题,同时,使得应用程序的测试,维护,和扩展更加容易.MVVM也可 ...

  5. ios入门第一天

    写在两个@ 之间的为oc语言   之外的为c语言  访问权限一旦定义了一个 除非在重新定义一个 否则都是该类型的 如 @protected  int i;  int j;  int l;int n; ...

  6. flask 文件的上传下载和excel操作

    文件的下载 from flask import send_from_directory @excel_bp.route('/get_attachment/<path:filename>') ...

  7. 【PL/SQL编程】块结构

    [DECLARE] --声明部分,可选 BEGIN --执行部分,必须 [EXCEPTION] --异常处理部分,可选 END

  8. jQuery 滑动选项卡jQuery tabulous.js

    A jQuery tabs module for todays web! 实例DEMO 运行一下 Documentation Tabulous.js can be used with any cont ...

  9. react中路由的跳转

    1.react-router-dom 使用react-router-dom 4.4.2 在页面中直接使用 引入 i mport { Link } from 'react-router-dom' 使用 ...

  10. 从互联网进化的角度看AI+时代的巨头竞争

    今天几乎所有的互联网公司在谈论和布局人工智能,收购相关企业.人工智能和AI+成为当今科技领域最灸手可热的名词,关于什么是AI+,其概念就是用以表达将"人工智能"作为当前行业科技化发 ...