xxHash - 编译, 库用法

文章目录

    • xxHash - 编译, 库用法
    • 概述
    • 笔记
    • xxHash的代码库地址
    • 编译
    • xxHash的用法
    • 自己搭建一个测试工程
    • 测试工程文件目录
    • 程序参数怎么给?
    • -H3
    • -H3 --binary
    • 自己写一个命令行工程, 对一个buffer来做hash
    • 测试工程(vs2019 vc++ console)
    • END

xxHash - 编译, 库用法

概述

给AES设置 key, iv时, 如果长度不够, 需要填充.
刚开始实现填充时, 用的固定内容, 感觉不太好.
看到github上有个xxHash工程, 很多星, 准备用这个工程来生成固定长度的hash来填充key, iv. 这样填充内容的随机性和确定性就好很多.
不管原始key, iv的长度多少, 都先用xxHash处理成符合AES要求的key, iv长度的buf, 再调用AES加解密函数, 这样就不用考虑key, iv的填充问题了.

笔记

xxHash的代码库地址

https://github.com/Cyan4973/xxHash.git

编译

迁出到本地
打开普通的cmd命令行

cd /d D:\3rd_prj\crypt\xxHash\cmake_unofficial
mkdir .\build
cd .\build
cmake -G "Visual Studio 16 2019" -A x64 ..
cmake --build .
cmake --build . --target install

库安装后的路径为 C:\Program Files\xxHash
目录内容如下:

C:\Program Files\xxHash>tree /F
文件夹 PATH 列表
卷序列号为 BA70-59B2
C:.
├─bin
│      xxhash.dll
│      xxhsum.exe
│
├─include
│      xxh3.h
│      xxhash.h
│
├─lib
│  │  xxhash.lib
│  │
│  ├─cmake
│  │  └─xxHash
│  │          xxHashConfig.cmake
│  │          xxHashConfigVersion.cmake
│  │          xxHashTargets-debug.cmake
│  │          xxHashTargets.cmake
│  │
│  └─pkgconfig
│          libxxhash.pc
│
└─share└─man└─man1xxhsum.1

现在就可以拿 /lib/xxhash.lib, /include/*.h, /bin/xxhash.dll包含到自己工程干活了.

xxHash的用法

看 xxhsum.exe的实现.
在编译目录中, 有xxhsum的VS工程实现.
在这里插入图片描述
打开 xxHash.sln
在这里插入图片描述
将xxhsum设置活动工程.
找到程序入口

/** The preferred method of obtaining the real UTF-16 arguments. Always works* on MSVC, sometimes works on MinGW-w64 depending on the compiler flags.*/
#ifdef __cplusplus
extern "C"
#endif
int __cdecl wmain(int argc, wchar_t* utf16_argv[])
{return XSUM_wmain(argc, utf16_argv);
}
#else /* !XSUM_WIN32_USE_WMAIN */

下断点, 单步单步xxhsum的实现, 大致看一下.

自己搭建一个测试工程

用安装后的xxHash库和xxhsum工程实现, 自己搭建一个独立测试工程.
整了一个命令行工程(cosole x64 debug), 将库拷贝到自己工程, 设置头文件包含路径和库路径
先加入xxhsum.c, 尝试编译, 确啥补啥.
官方cli工程里面包含xxhash.h时, 都是用…/xxhash.h, 改为xxhash.h
编译通过, 功能正常.

测试工程文件目录

D:\my_dev\my_local_git_prj\study\xxHash\my_xxhsum>tree /F
文件夹 PATH 列表
卷序列号为 36AD-51CE
D:.
│  my_xxhsum.sln
│  my_xxhsum.vcxproj
│  my_xxhsum.vcxproj.filters
│  my_xxhsum.vcxproj.user
│  xsum_arch.h
│  xsum_bench.c
│  xsum_bench.h
│  xsum_config.h
│  xsum_os_specific.c
│  xsum_os_specific.h
│  xsum_output.c
│  xsum_output.h
│  xsum_sanity_check.c
│  xsum_sanity_check.h
│  xxhsum.c
│
└─xxHash_lib├─bin│      xxhash.dll│      xxhsum.exe│├─include│      xxh3.h│      xxhash.h│├─lib│  │  xxhash.lib│  ││  ├─cmake│  │  └─xxHash│  │          xxHashConfig.cmake│  │          xxHashConfigVersion.cmake│  │          xxHashTargets-debug.cmake│  │          xxHashTargets.cmake│  ││  └─pkgconfig│          libxxhash.pc│└─share└─man└─man1xxhsum.1

程序参数怎么给?

static int XSUM_usage(const char* exename)
{XSUM_log( WELCOME_MESSAGE(exename) );XSUM_log( "Print or verify checksums using fast non-cryptographic algorithm xxHash \n\n" );XSUM_log( "Usage: %s [options] [files] \n\n", exename);XSUM_log( "When no filename provided or when '-' is provided, uses stdin as input. \n");XSUM_log( "\nOptions: \n");XSUM_log( "  -H#          select an xxhash algorithm (default: %i) \n", (int)g_defaultAlgo);XSUM_log( "               0: XXH32 \n");XSUM_log( "               1: XXH64 \n");XSUM_log( "               2: XXH128 (also called XXH3_128bits) \n");XSUM_log( "               3: XXH3 (also called XXH3_64bits) \n");XSUM_log( "  -c, --check  read xxHash checksum from [files] and check them \n");XSUM_log( "  -h, --help   display a long help page about advanced options \n");return 0;
}static int XSUM_usage_advanced(const char* exename)
{XSUM_usage(exename);XSUM_log( "\nAdvanced :\n");XSUM_log( "  -V, --version        Display version information \n");XSUM_log( "      --tag            Produce BSD-style checksum lines \n");XSUM_log( "      --little-endian  Checksum values use little endian convention (default: big endian) \n");XSUM_log( "      --binary         Read in binary mode \n");XSUM_log( "  -b                   Run benchmark \n");XSUM_log( "  -b#                  Bench only algorithm variant # \n");XSUM_log( "  -i#                  Number of times to run the benchmark (default: %i) \n", NBLOOPS_DEFAULT);XSUM_log( "  -q, --quiet          Don't display version header in benchmark mode \n");XSUM_log( "\n");XSUM_log( "The following five options are useful only when verifying checksums (-c): \n");XSUM_log( "  -q, --quiet          Don't print OK for each successfully verified file \n");XSUM_log( "      --status         Don't output anything, status code shows success \n");XSUM_log( "      --strict         Exit non-zero for improperly formatted checksum lines \n");XSUM_log( "      --warn           Warn about improperly formatted checksum lines \n");XSUM_log( "      --ignore-missing Don't fail or report status for missing files \n");return 0;
}

给出不同命令行参数, 试试效果.

-H3

-H3 D:\my_tmp\my_xxhsum.pdb
结果如下:
\XXH3_82fc89454f8a2238  D:\\my_tmp\\my_xxhsum.pdb

-H3 --binary

-H3 --binary D:\my_tmp\my_xxhsum.pdb
结果如下:
\XXH3_82fc89454f8a2238  D:\\my_tmp\\my_xxhsum.pdb

看来都是2进制读取文件内容并计算hash.
单步时, 发现 --binary 是无效的, 被忽略掉了

 if (!strcmp(argument, "--binary")) { continue; } /* Just ignore it. See https://github.com/Cyan4973/xxHash/issues/812 */

算hash的cli函数

return XSUM_hashFiles(argv+filenamesStart, argc-filenamesStart, algo, displayEndianess, convention);

看到使用xxHash库的最终用法了

/** XSUM_hashStream:* Reads data from `inFile`, generating an incremental hash of type hashType,* using `buffer` of size `blockSize` for temporary storage.*/
static Multihash
XSUM_hashStream(FILE* inFile,AlgoSelected hashType,void* buffer, size_t blockSize)
{XXH32_state_t state32;XXH64_state_t state64;XXH3_state_t  state3;/* Init */(void)XXH32_reset(&state32, XXHSUM32_DEFAULT_SEED);(void)XXH64_reset(&state64, XXHSUM64_DEFAULT_SEED);(void)XXH3_128bits_reset(&state3);/* Load file & update hash */{   size_t readSize;while ((readSize = fread(buffer, 1, blockSize, inFile)) > 0) {switch(hashType){case algo_xxh32:(void)XXH32_update(&state32, buffer, readSize);break;case algo_xxh64:(void)XXH64_update(&state64, buffer, readSize);break;case algo_xxh128:(void)XXH3_128bits_update(&state3, buffer, readSize);break;case algo_xxh3:(void)XXH3_64bits_update(&state3, buffer, readSize);break;default:assert(0);}}if (ferror(inFile)) {XSUM_log("Error: a failure occurred reading the input file.\n");exit(1);}   }{   Multihash finalHash = {0};switch(hashType){case algo_xxh32:finalHash.hash32 = XXH32_digest(&state32);break;case algo_xxh64:finalHash.hash64 = XXH64_digest(&state64);break;case algo_xxh128:finalHash.hash128 = XXH3_128bits_digest(&state3);break;case algo_xxh3:finalHash.hash64 = XXH3_64bits_digest(&state3);break;default:assert(0);}return finalHash;}
}

保存Hash值

    /* display Hash value in selected format */switch(hashType){case algo_xxh32:{   XXH32_canonical_t hcbe32;(void)XXH32_canonicalFromHash(&hcbe32, hashValue.hash32);f_displayLine(fileName, &hcbe32, hashType);break;}case algo_xxh64:{   XXH64_canonical_t hcbe64;(void)XXH64_canonicalFromHash(&hcbe64, hashValue.hash64);f_displayLine(fileName, &hcbe64, hashType);break;}case algo_xxh128:{   XXH128_canonical_t hcbe128;(void)XXH128_canonicalFromHash(&hcbe128, hashValue.hash128);f_displayLine(fileName, &hcbe128, hashType);break;}case algo_xxh3:{   XXH64_canonical_t hcbe64;(void)XXH64_canonicalFromHash(&hcbe64, hashValue.hash64);f_displayLine(fileName, &hcbe64, hashType);break;}default:assert(0);  /* not possible */}

显示hash值

static void XSUM_printLine_GNU(const char* filename,const void* canonicalHash, const AlgoSelected hashType)
{XSUM_printLine_GNU_internal(filename, canonicalHash, hashType, XSUM_display_BigEndian);
}
static void XSUM_printLine_GNU_internal(const char* filename,const void* canonicalHash, const AlgoSelected hashType,XSUM_displayHash_f f_displayHash)
{assert(0 <= hashType && (size_t)hashType <= XSUM_TABLE_ELT_SIZE(XSUM_algoName));{   const size_t hashLength = XSUM_algoLength[hashType];const int needsEscape = XSUM_filenameNeedsEscape(filename);if (needsEscape) {XSUM_output("%c", '\\');}XSUM_displayPrefix(hashType);f_displayHash(canonicalHash, hashLength);XSUM_output("  ");XSUM_printFilename(filename, needsEscape);XSUM_output("\n");
}   }
static void XSUM_display_BigEndian(const void* ptr, size_t length)
{const XSUM_U8* const p = (const XSUM_U8*)ptr;size_t idx;for (idx=0; idx<length; idx++)XSUM_output("%02x", p[idx]);
}

懂了

自己写一个命令行工程, 对一个buffer来做hash

官方工程是针对文件做hash, 我要的是对buffer做hash.
通过单步, 这个库的用法已经清楚了. 自己来整一遍, 只不过, 我要的是对buffer做hash.
整完了, 好使
在这里插入图片描述
在xxHash基础上, 封装了3个应用接口:

bool buffer_hash_XXH3_32bits(uint8_t* pBuf, size_t nLenBuf, uint32_t& hash_4Byte);
bool buffer_hash_XXH3_64bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_8Byte);
bool buffer_hash_XXH3_128bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_H8Byte, uint64_t& hash_K8Byte);

用这3个应用接口来做流的hash, 就方便多了.

测试工程(vs2019 vc++ console)

// @file test_xxHash_form_buffer.cpp#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>#define XXH_STATIC_LINKING_ONLY   // 在包含xxhash.h之前, 必须定义这个宏
#include "xxhash.h"#pragma comment(lib, "xxhash.lib")bool buffer_hash_XXH3_32bits(uint8_t* pBuf, size_t nLenBuf, uint32_t& hash_4Byte);
bool buffer_hash_XXH3_64bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_8Byte);
bool buffer_hash_XXH3_128bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_H8Byte, uint64_t& hash_K8Byte);void test_hash_128();
void test_hash_64();
void test_hash_32();int main()
{printf("test xxHash from buffer\n");test_hash_128();test_hash_64();test_hash_32();return 0;
}void test_hash_128()
{uint64_t hash_H8Byte = 0;uint64_t hash_L8Byte = 0;char szBuf[0x100];memset(szBuf, 0, sizeof(szBuf));strcpy(szBuf, "hello xxHash 128"); // add vs option _CRT_SECURE_NO_WARNINGSsize_t nLenBuf = strlen(szBuf);if (buffer_hash_XXH3_128bits((uint8_t*)szBuf, nLenBuf, hash_H8Byte, hash_L8Byte)){printf("hash value =  %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X",(uint8_t)(((hash_H8Byte >> (8 * 7)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 6)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 5)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 4)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 3)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 2)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 1)) & 0xff)),(uint8_t)(((hash_H8Byte >> (8 * 0)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 7)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 6)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 5)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 4)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 3)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 2)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 1)) & 0xff)),(uint8_t)(((hash_L8Byte >> (8 * 0)) & 0xff)));printf("\n");}else {printf("error\n");}
}void test_hash_64()
{uint64_t hash_8Byte = 0;char szBuf[0x100];memset(szBuf, 0, sizeof(szBuf));strcpy(szBuf, "hello xxHash 64"); // add vs option _CRT_SECURE_NO_WARNINGSsize_t nLenBuf = strlen(szBuf);if (buffer_hash_XXH3_64bits((uint8_t*)szBuf, nLenBuf, hash_8Byte)){printf("hash value =  %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X",(uint8_t)(((hash_8Byte >> (8 * 7)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 6)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 5)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 4)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 3)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 2)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 1)) & 0xff)),(uint8_t)(((hash_8Byte >> (8 * 0)) & 0xff)));printf("\n");}else {printf("error\n");}
}void test_hash_32()
{uint32_t hash_4Byte = 0;char szBuf[0x100];memset(szBuf, 0, sizeof(szBuf));strcpy(szBuf, "hello xxHash 32"); // add vs option _CRT_SECURE_NO_WARNINGSsize_t nLenBuf = strlen(szBuf);if (buffer_hash_XXH3_32bits((uint8_t*)szBuf, nLenBuf, hash_4Byte)){printf("hash value =  %2.2X %2.2X %2.2X %2.2X",(uint8_t)(((hash_4Byte >> (8 * 3)) & 0xff)),(uint8_t)(((hash_4Byte >> (8 * 2)) & 0xff)),(uint8_t)(((hash_4Byte >> (8 * 1)) & 0xff)),(uint8_t)(((hash_4Byte >> (8 * 0)) & 0xff)));printf("\n");}else {printf("error\n");}
}bool buffer_hash_XXH3_128bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_H8Byte, uint64_t& hash_K8Byte)
{bool b_rc = false;XXH3_state_t  state3;XXH128_hash_t finalHash;do {// size_t 没有负数if ((NULL == pBuf) || (nLenBuf <= 0)){break;}(void)XXH3_128bits_reset(&state3);(void)XXH3_128bits_update(&state3, pBuf, nLenBuf);finalHash = XXH3_128bits_digest(&state3);hash_H8Byte = finalHash.high64;hash_K8Byte = finalHash.low64;b_rc = true;} while (false);return b_rc;
}bool buffer_hash_XXH3_64bits(uint8_t* pBuf, size_t nLenBuf, uint64_t& hash_8Byte)
{bool b_rc = false;XXH3_state_t  state3;XXH64_hash_t finalHash;do {// size_t 没有负数if ((NULL == pBuf) || (nLenBuf <= 0)){break;}(void)XXH3_128bits_reset(&state3);(void)XXH3_64bits_update(&state3, pBuf, nLenBuf);finalHash = XXH3_64bits_digest(&state3);hash_8Byte = finalHash;b_rc = true;} while (false);return b_rc;
}bool buffer_hash_XXH3_32bits(uint8_t* pBuf, size_t nLenBuf, uint32_t& hash_4Byte)
{bool b_rc = false;XXH32_state_t state32;XXH32_hash_t finalHash;do {// size_t 没有负数if ((NULL == pBuf) || (nLenBuf <= 0)){break;}// #define XXHSUM32_DEFAULT_SEED 0                   /* Default seed for algo_xxh32 */(void)XXH32_reset(&state32, 0 /*XXHSUM32_DEFAULT_SEED*/);(void)XXH32_update(&state32, pBuf, nLenBuf);finalHash = XXH32_digest(&state32);hash_4Byte = finalHash;b_rc = true;} while (false);return b_rc;
}

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/313806.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12.29最小生成数K算法复习(注意输入输出格式),校园最短路径(通过PRE实现路径输出,以及输入输出格式注意)

7-2 最小生成树-kruskal算法 分数 15 const int maxn 1000; struct edge {int u, v, w; }e[maxn]; int n, m, f[30]; bool cmp(edge a, edge b) {return a.w < b.w; } int find(int x) {if (f[x] x) {return x;}else {f[x] find(f[x]);return f[x];} } //int arr[100…

10. UVM Environment

环境为agents, scoreboards和其他验证组件&#xff08;包括有助于在 SoC 级别重用块级环境组件的其他环境类&#xff09;提供良好的层次结构和容器。用户定义的 env 类必须从 uvm_env 类扩展。 10.1 uvm_env class hierarchy 类声明&#xff1a; virtual class uvm_env extend…

Android长按图标展示快捷方式

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {new Thread(() -> {// 获取ShortcutManager实例ShortcutManager shortcutManager getSystemService(ShortcutManager.class);// 创建要添加的快捷方式ShortcutInfo.Builder shortcutBuilder new ShortcutInfo.Bui…

数据结构模拟实现LinkedList双向不循环链表

目录 一、双向不循环链表的概念 二、链表的接口 三、链表的方法实现 &#xff08;1&#xff09;display方法 &#xff08;2&#xff09;size方法 &#xff08;3&#xff09;contains方法 &#xff08;4&#xff09;addFirst方法 &#xff08;5&#xff09;addLast方法 …

【Java基础篇】While(true) 和 for(;;)哪个性能更好呢

两个无限循环的性能分析 ✔️两者反编译比较 ✔️两者反编译比较 While(true) 和 for(; &#x1f609; 都是做无限循环的代码&#xff0c;他们两个有什么区别呢&#xff1f; 关于这个问题&#xff0c;网上有很多的讨论&#xff0c;今天我收到私信&#xff0c;所以凑着假期&…

软件功耗管理

一、背景 功耗管理是由软件、处理器、外设、电源等一起构成的系统问题。 App中很小的低效行为在整个系统中累加后&#xff0c;会对电池寿命、性能、响应速度和温度产生明显的影响。作为app开发人员&#xff0c;我们有责任确保我们的app尽可能高效地运行。使用苹果推荐的API&a…

消息队列LiteQueue

文章目录 一、简介二、设计2.1 队列结构设计2.2 队列接口设计 三、实现3.1 队列锁的实现3.2 创建队列3.3 写入队列3.4 读出数据3.5 判断队列是否为空3.6 判断队列是否为满3.7 清空队列3.8 删除队列 四、测试参考 一、简介 收到消息时先把接收到的消息放到队列中。在任务中从队…

31K star!替换Postman ,开源优雅的API工具:Insomnia

API 调试工具大家第一个想到的肯定是Postman&#xff0c;但是这几年Postman在国内越来越难用&#xff0c;很多人也都在考虑找一个替代品。 今天我们来推荐一个可以替换掉Postman的 API 工具&#xff0c;他开源、支持本地使用&#xff0c;也更加轻量、更加优雅&#xff0c; 目前…

ROS TF坐标变换 - TF树

目录 一、TF树介绍二、TF2与TF三、构建TF树四、rviz查看TF坐标关系 一、TF树介绍 在机器人系统中&#xff0c;存在运动学模型和动力学模型。对于刚体机器人&#xff0c;动力学模型基于刚体动力学&#xff0c;代表机器人系统在运动过程中力/力矩与其运动状态的变化关系。而运动…

Python 基础语法01

变量声明 #运算 num 1 num 1 print("num 1",num)num - 1 print("num - 1", num)num * 4 print("num * 4",num)num 3 num % 2 print("num%2",num)num ** 2 print("num ** 2", num)num 9 num // 2 print("num // …

odoo17 | 创建一个新应用程序

前言 本章的目的是为创建一个全新的Odoo模块奠定基础。 我们将从头开始&#xff0c;以使我们的模块被Odoo识别所需的最低限度。 在接下来的章节中&#xff0c;我们将逐步添加功能以构建一个真实的业务案例。 教程 假设我门需要在odoo上开发一个新app模块例如房地产广告模块。…

C++的面向对象学习(9):文件操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、类的封装的多文件实现回顾二、文件操作1.对文件进行操作需要头文件<fstream>2.操作文件的三大类方法&#xff1a;读、写、读写 三、实现文本文件的读、写…