相关文章推荐
卖萌的葡萄酒  ·  android - ...·  1 年前    · 
独立的皮带  ·  gcloud命令说 "pyenv: ...·  1 年前    · 
宽容的领带  ·  .NET ...·  1 年前    · 
1.2.使用注意事项: 哈希函数实现通常调用boost::hash,boost::hash_range 或没有命名空间限定boost::hash_combine(以便通过 ADL 找到自定义类型重载) 通常不应由用户直接调用hash_value 相同的参数应产生相同的结果 1.2.函数: void hash_combine(size_t &, T const&);组合多个值产生hash-顺序有关 注3 std::size_t hash_range(It, It); 计算迭代器范围哈希-顺序有关 注4 void hash_range(std::size_t&, It, It); std::size_t hash_value(T);基本类型 注1,2 std::size_t hash_value(T* const&); std::size_t hash_value(T (&val)[unsigned N]); std::size_t hash_value(const T (&val)[N]); 1.3.使用方法: 1)系统支持的类型直接使用-创建实例并将其作为函数调用 boost::hash string_hash; std::size_t h = string_hash("Hash me"); 2)自定义类型 类内重载比较运算符,重载friend hash_value(命名空间同类) 不同于C++的std::hash; 相同类型元素不同hash值不同; 不同类型的数据的hash值可能相等;
注1:基本类型包括 
    bool, char, signed char, unsigned char, wchar_t, char16_t, char32_t, 
    short, unsigned short, int, unsigned int, long, unsigned long
    long long, unsigned long long,float, double, long double,
注2:STL无序容器,标准容器
    std:basic_string(string,wstring,u16string,u32string,type_index),T*
    std::array,std::pair,vector,list,deque,set,multiset,map,multimap
    std::complex<T>,tuple
注3:boost::hash_combine
用途:重复调用以从多个变量增量创建哈希值
注意:使用调用顺序时很重要;计算数据哈希值,数据顺序在比较中并不重要,
    必须确保数据始终以相同顺序提供
    std::size_t seed = 0;
    hash_combine(seed, 1);hash_combine(seed, 2);不同于:
    boost::hash_combine(seed, 2);boost::hash_combine(seed, 1);
注4:boost::hash_range
用途:计算迭代器范围的哈希;对元素顺序敏感,不适合无序容器使用
    size_t seed = 0;
    for(; first != last; ++first){hash_combine(seed, *first);}//两参数
    for(; first != last; ++first){hash_combine(seed, *first);}//三参数
    std::vector<std::string> some_strings;
    std::size_t hash = boost::hash_range(some_strings.begin(), some_strings.end()); 
在编写模板类时,您可能不想包含主哈希标头,因为它是一个非常昂贵的包含, 会带来许多其他标头,因此可包含<boost/container_hash/hash_fwd.hpp> forward 声明的标头boost::hash,boost::hash_range和boost::hash_combine. 在实例化boost::hash.当使用使用boost::hash它的容器时,应该为您执行此操作, 因此您的类型将与 boost 哈希容器一起正常工作。 #include <boost/container_hash/hash_fwd.hpp> template <typename A, typename B> class my_pair{ A value1; B value2; public: my_pair(A const& v1, B const& v2): value1(v1), value2(v2){} bool operator==(my_pair const& b) const{return value1 == b.value1 &&value2 == b.value2;} friend std::size_t hash_value(my_pair const& p){ std::size_t seed = 0; boost::hash_combine(seed, p.value1); boost::hash_combine(seed, p.value2); return seed;
注6:可移植性
    boost::hash尽可能支持可移植,一些较旧编译器不支持参数相关查找(ADL) - 用于定制的机制
    hash_value在这些编译器上,需要在命名空间中声明自定义重载boost
    在严格符合标准的编译器上,在实例化boost时不会找到命名空间中定义的重载boost::hash,
    因此对于这些编译器,重载只能在与类相同的命名空间中声明。
2.实例:
实例1:通用使用
#include <boost/container_hash/hash.hpp>
实例2:通用使用-生成的向量包含容器元素哈希值的函数
template <class Container>
std::vector<std::size_t> get_hashes(Container const& x){
    std::vector<std::size_t> hashes;
    std::transform(x.begin(), x.end(), std::back_inserter(hashes),
        boost::hash<typename Container::value_type>());
    return hashes;
实例3:自定义类型
    boost::hash通过调用hash_value来实现。未指定命名空间,以便它可通过参数查找相关重载
    因此如hash_value在与自定义类型相同的命名空间中有一自由函数,它将被调用
实例3.1:自定义hash函数
#include <cstddef>
#include <string>
namespace tcy{
    struct book{int id;std::string author;std::string title;};
    bool operator==(book const& a, book const& b){return a.id == b.id;}
//编写函数tcy::hash_value:
namespace tcy{
    std::size_t hash_value(book const& b){boost::hash<int> hasher;return hasher(b.id);}
//使用boost::hash:
void test(){
    tcy::book b1(100, "Tom");
    tcy::book b2(101, "Bob");
    boost::hash<tcy::book> book_hasher;
    std::size_t b1_hash = book_hasher(b1);
    std::unordered_set<tcy::book, boost::hash<tcy::book> > books;
    books.insert(b1);
    books.insert(tcy::book(102, "Jim"));
    books.insert(tcy::book(103, "Aimla"));
    assert(books.find(b1) != books.end());
    assert(books.find(b2) == books.end());
实例3.2:自定义hash函数-组合哈希值
点类希望将其用作 unordered_map 的键。需要为此结构自定义散列。
需要组合 x 和 y 的哈希值。boost::hash_combine为此目的提供了该函数
class point{
    int x;
    int y;
public:
    point() : x(0), y(0) {}
    point(int x, int y) : x(x), y(y) {}
    bool operator==(point const& b) const{ return x == b.x && y == b.y;}
    friend std::size_t hash_value(point const& p){
        std::size_t seed = 0;
        boost::hash_combine(seed, p.x);
        boost::hash_combine(seed, p.y);
        return seed;
int main(){
    boost::hash<point> point_hasher;
    point p1(0, 0);
    point p2(1, 2);
    point p3(4, 1);
    point p4 = p1;
    assert(point_hasher(p1) == point_hasher(p4));
    // 测试可能会失败,如失败那将是一相当糟糕的哈希函数
    assert(point_hasher(p1) != point_hasher(p2));
    assert(point_hasher(p1) != point_hasher(p3));

 实例4:完整实例 头文件

#pragma once
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <type_traits>
//#include <boost/container_hash/hash_fwd.hpp>
#include <boost/container_hash/hash.hpp>
namespace bs = boost;
using namespace std::string_literals;
template <class Container>
std::vector<std::size_t> get_hashes(Container const& x) {
	std::vector<std::size_t> hashes;
	std::transform(x.begin(), x.end(), std::back_inserter(hashes),
		boost::hash<typename Container::value_type>());
	return hashes;
namespace tcy {
	struct Book { int id; std::string author; };
	bool operator==(Book const& a, Book const& b);
	std::size_t hash_value(Book const& b);
class Point {
    int x;
    int y;
public:
    Point() : x(0), y(0) {}
    Point(int x, int y) : x(x), y(y) {}
    bool operator==(Point const& b) const { return x == b.x && y == b.y; }
    friend std::size_t hash_value(Point const& p) {
        std::size_t seed = 0;
        boost::hash_combine(seed, p.x);
        boost::hash_combine(seed, p.y);
        return seed;
namespace tc {//推荐用法
	template <class T> class A {
	public:
		A(T x) : x(x) {}
		bool operator==(A const& b) { return x == b.x; }            //可定义为成员或普通函数
		//std::size_t hash_value() { return boost::hash<T>()(x); }  //error不能定义为类成员函数
		friend std::size_t hash_value(const A<T>& a) { return boost::hash<T>()(a.x); }
namespace tc {//备选用法-编译器若不支持模板friend(不支持 ADL 的编译器)
	// (不能声明为friend hash_value)hash_value需要在boost命名空间中定义
	template <class T> class A1 {
	public:
		A1(T x) : x(x) {}
		bool operator==(A1 const& b) { return x == b.x; }//可定义为成员或普通函数
		std::size_t hash() const {return boost::hash<T>()(x); }
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
namespace boost
#else
namespace tc
    template <class T>std::size_t hash_value(A1<T> x){return x.hash();}
#endif
void test_boost_hash();
//***********************************************************
// 以上测试boost库hash;以下测试C++ std::hash
struct B{
	int x;
	std::string s;
    B() :s(""), x(0) {}
    B(int x,const std::string& s) :s(s), x(x) {}
    bool operator==(const B& rhs) const { return (x == rhs.x) && (s == rhs.s); }  //必须重载  
//将自己的偏特化加入到std中
namespace std{
    template<> struct hash<B> {
        size_t operator()(const B& rhs) const noexcept{
            return (std::hash<int>()(rhs.x)) ^ (std::hash<std::string>()(rhs.s) << 1);}
class B1{
public:
    std::string name;
    std::string age;
    B1(std::string name,std::string age) :name(name),age(age) {}
    bool operator ==(const B1& c) const{
        return (name == c.name && age == c.age);}
class B1hash{
public:
    std::size_t operator()(const B1& c) const{
        return hash_val(c.name,c.age);}
    template <typename... Types>
    size_t hash_val(const Types&... args)const{
        size_t seed = 0;
        hash_value(seed, args...);
        return seed;
    template <typename T, typename... Types>
    void hash_value(size_t& seed,const T& firstArg,const Types&... args) const{
        hash_combine(seed, firstArg);
        hash_value(seed, args...);
    template <typename T>
    void hash_value(size_t& seed,const T& val) const{
        hash_combine(seed, val);
    template<typename T>
    void hash_combine(size_t& seed,const T& val) const{
        seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
struct Point_ { 
    double x=0, y=0; 
    Point_() = default;
    Point_(double x, double y) :x(x),y(y) {}
struct Point_Cmp {
    bool operator()(const Point_& lhs, const Point_& rhs) const {
        return lhs.x < rhs.x; // NB. intentionally ignores y
template<typename Point_>
class T_hash {
public:
    size_t operator()(const Point_& s) const {
        size_t h1 = std::hash<double>()(s.x);
        size_t h2 = std::hash<double>()(s.y);
        return h1 ^ (h2 << 1);
class t_hash {
public:
    size_t operator()(const Point_& s) const {
        size_t h1 = std::hash<double>()(s.x);
        size_t h2 = std::hash<double>()(s.y);
        return h1 ^ (h2 << 1);
void test_cpuls_hash();
#include "boost_hash.h"
#include <iostream>
#include <cassert>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <any>
bool tcy::operator==(tcy::Book const& a, tcy::Book const& b) { return a.id == b.id; }
std::size_t tcy::hash_value(tcy::Book const& b) { boost::hash<int> hasher; return hasher(b.id); }
void _test_int_boost_hash() {
	int x = 1; 
	assert(bs::hash<int>()(x) == 1);
	assert(bs::hash<unsigned>()(x) == 1);
	assert(bs::hash<long>()(x) == 1);
	assert(bs::hash<long long>()(x) == 1);
	assert(bs::hash<size_t>()(x) == 1);
	assert(bs::hash<const int>()(x) == 1);
	int& rx = x; const int& crx = x;
	assert(bs::hash<int&>()(rx) == 1);
	assert(bs::hash<const int&>()(crx) == 1);
	int* px = &x;
	auto h1 = bs::hash<int*>()(px);
	const int* cpx = &x; 
	auto h2 = bs::hash<const int*>()(cpx);
	int* const pcx = &x; 
	auto h3 = bs::hash<int* const>()(pcx);
	assert(h1 == h2 && h2 == h3);//h1每次运行的值都不同
	assert(bs::hash<int>()(1) != bs::hash<double>()(1));
void _test_str_boost_hash() {
	auto h = bs::hash<char>()('a');
	assert(h == bs::hash<unsigned char>()('a'));
	assert(h != bs::hash<std::string>()("a"s));
	h = bs::hash<const char*>()("Tom");
	assert(h != bs::hash<std::string>()("Tom"s));
size_t hash_vec(const std::vector<int>& vec) {return bs::hash<std::vector<int>>()(vec); }
size_t hash_vec(const std::vector<double>& vec) { return bs::hash<std::vector<double>>()(vec); }
size_t hash_vec_range(const std::vector<int>& vec) { return boost::hash_range(vec.begin(), vec.end()); }
size_t hash_vec_range(const std::vector<double>& vec) { return boost::hash_range(vec.begin(), vec.end()); }
void _test_vector_boost_hash() {
	std::size_t h{}, h1{}, h2{};
	int x = 0;
	std::vector<int> vec;
	std::vector<double> dvec;
	assert(bs::hash<int>()(x) == 0);
	assert(hash_vec(vec) == 0);
	assert(hash_vec(dvec) == 0);
	assert(hash_vec_range(vec) == 0);
	vec = { 2 };
	assert(bs::hash<int>()(2) == 2);
	assert(hash_vec(vec) == 10832819064819134812);
	assert(hash_vec_range(vec) == 10832819064819134812);
	dvec = { 2 };
	assert(hash_vec(dvec) == 551290964831955812);
	assert(hash_vec_range(dvec) == 551290964831955812);
	vec = { 1,2,3 };
	assert(hash_vec(vec) == hash_vec_range(vec));
void _test_set_boost_hash() {
	std::size_t h{};
	std::set<int> set;
	h = boost::hash_range(set.begin(), set.end());
	assert(h == 0);
	set={ 1, 2, 3, 4, 5 };
	h = boost::hash_range(set.begin(), set.end());
	assert(h == 10158794003290771518);
//使用boost::hash:
void test_book_boost_hash() {
	tcy::Book b1{ 100, "Tom"s };
	tcy::Book b2{ 101, "Bob"s };
	boost::hash<tcy::Book> book_hasher;
	std::size_t b1_hash = book_hasher(b1);
	std::unordered_set<tcy::Book, boost::hash<tcy::Book> > books;
	books.insert(b1);
	books.insert(tcy::Book{ 102, "Jim" });
	books.insert(tcy::Book{ 103, "Aimla" });
	assert(books.find(b1) != books.end());
	assert(books.find(b2) == books.end());
void test_point_boost_hash() {
	boost::hash<Point> point_hasher;
	Point p1(0, 0);
	Point p2(1, 2);
	Point p3(4, 1);
	Point p4 = p1;
	assert(point_hasher(p1) == point_hasher(p4));
	// 测试可能会失败,如失败那将是一相当糟糕的哈希函数
	assert(point_hasher(p1) != point_hasher(p2));
	assert(point_hasher(p1) != point_hasher(p3));
void test_hash_combine() {
	//使用boost::hash_combine调用顺序时很重要
	std::size_t seed = 0;
	boost::hash_combine(seed, 1);
	boost::hash_combine(seed, 2);
	//产生不同的种子:
	std::size_t seed2 = 0;
	boost::hash_combine(seed2, 2);
	boost::hash_combine(seed2, 1);
	assert(seed != seed2);
void test_hash_range() {//计算迭代器范围的哈希
	std::vector<std::string> vecstr;
	std::size_t hash = boost::hash_range(vecstr.begin(), vecstr.end());
	assert(hash == 0);
	vecstr = {"Tom", "Bob"};
	hash = boost::hash_range(vecstr.begin(), vecstr.end());
	std::cout << "vector<string> hash=" << hash << std::endl;//1859127738627118395
void test_custom_type_boost_hash() {
	tc::A<int> x1(1), x2(2), x3(1);
	boost::hash<tc::A<int> > hasher;
	assert(hasher(x1) == hasher(x1));
	assert(hasher(x1) != hasher(x2));
	assert(hasher(x1) == hasher(x3));
	tc::A1<int> y1(1), y2(2), y3(1);
	boost::hash<tc::A1<int> > hasher1;
	assert(hasher1(y1) == hasher1(y1));
	assert(hasher1(y1) != hasher1(y2));
	assert(hasher1(y1) == hasher1(y3));
void test_boost_hash() {
	_test_int_boost_hash();
	_test_str_boost_hash();
	_test_vector_boost_hash();
	_test_set_boost_hash();
	test_book_boost_hash();//使用boost::hash
	test_point_boost_hash();
	test_hash_combine();
	test_hash_range();
	test_custom_type_boost_hash();
void _test_cpuls_int_hash() {
	int x = 1; 
	int* px = &x; const int* cpx = &x;
	//去除限定符的int,long,size_t值(恒定)都相同
	assert(bs::hash<int>()(x) == 1);
	assert(std::hash<int>()(x) == 12478008331234465636);
	//去除限定符的*int,*long,*size_t值(每次运行都不同)都相同
	assert(bs::hash<int*>()(px) == bs::hash<const int*>()(cpx));
void _test_cpuls_vector_hash() {
	auto h = std::hash<std::string>()("Tom"s);
	std::vector<bool>vec;
	h = std::hash<std::vector<bool>>()(vec);
void test_cpuls_Point_hash() {
	using std::cout;
	using std::endl;
    Point_ p1, p2;
    std::hash<Point_*> hp;
	assert(hp(&p1)!=hp(&p2));//指针类型每次运行值不同
	assert(T_hash<Point_>()(p1) == 17962616281243732559);
	assert(T_hash<Point_>()(p2) == 17962616281243732559);
	assert(t_hash()(p1) == 17962616281243732559);
	assert(t_hash()(p2) == 17962616281243732559);
    std::any a1 = 1,a2 = 1;
    std::hash<std::any*> hash_any;
	assert(hash_any(&a1)!= hash_any(&a2));
void _test_cpuls_B_hash(){
	B b,b1(1011,"Tom"s), b2(1012, "Bob"s) ;
	assert(std::hash<B>()(b) == 15762686341408249279);
	std::unordered_map<B, int> map;
	//std::unordered_map<B, int, std::hash<B>> map;//参数3可写可不写
	map.insert({ b,10 });
	map.insert({ b1,20 });
	map.insert({ b2,30 });
void _test_cpuls_B1_hash(){
	std::unordered_multiset<B1, B1hash> set;
void test_cpuls_hash() {
	_test_cpuls_int_hash();
	_test_cpuls_B_hash();
	_test_cpuls_B1_hash();
	test_cpuls_Point_hash();
$router.path 
 console . log ( $router . path ) ; // aaa/bbb/ccc?x=1&y=2&y=3&z
$router . path = 'ccc/ddd' ;
console . log ( $router . path ) ; // ccc/ddd
$router.pathname 
 console . log ( $router . pathname ) ; // aaa/bbb/ccc
$router . pathname = 'ccc/ddd' ;
console . log ( $router . path ) ; // ccc/ddd?x=1&y=2&y=3&z
$router.search 
 console . log ( $router .
				
赠送jar包:shiro-crypto-hash-1.4.0.jar; 赠送原API文档:shiro-crypto-hash-1.4.0-javadoc.jar; 赠送源代码:shiro-crypto-hash-1.4.0-sources.jar; 赠送Maven依赖信息文件:shiro-crypto-hash-1.4.0.pom; 包含翻译后的API文档:shiro-crypto-hash-1.4.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.shiro:shiro-crypto-hash:1.4.0; 标签:apache、shiro、crypto、hash、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。 go get github.com/mmcloughlin/geohash 并将其导入到您的程序中 import "github.com/mmcloughlin/geohash" func ConvertIntToString func ConvertIntToString ( hash uint64 , chars uint ) string ConvertIntToString将整数geohash转换为具有chars字符的等效字符串geohash。 提供的整数geohash被解释为具有5 * chars的精度。 func ConvertStringToInt func ConvertStringToInt ( hash string ) ( uint64 , uint ) Conve
boost :: hash_combine从类的不同成员生成哈希值实现功能C++实现代码 Boost的container_hash模块,boost :: hash_combine从类的不同成员生成哈希值 C++实现代码 #if defined(NDEBUG) #undef NDEBUG #endif #include <boost/container_hash/hash.hpp> #include <cassert> class point int x;
Boost使用boost :: hashboost :: array的测试实现功能C++实现代码 使用boost :: hashboost :: array的测试 C++实现代码 #include <string> #include <iostream> #include <boost/array.hpp> #include <algorithm> #include <boost/functional/hash.hpp> #incl
C++实现代码 #include <boost/range/iterator_range_hash.hpp> #include <boost/test/test_tools.hpp> #include <boost/test/unit_test.hpp> #include <vector> namespace boost_rang
geohash是一种将地理位置编码为字符串的方法,可以在Python中使用geohash库来实现。该库提供了将经纬度转换为geohash编码的函数,以及将geohash编码转换为经纬度的函数。使用该库可以方便地进行地理位置的编码和解码操作。例如,可以使用以下代码将一个经纬度转换为geohash编码: import geohash lat = 39.9042 lon = 116.4074 gh = geohash.encode(lat, lon) print(gh) 输出结果为: wx4gec 同样地,可以使用以下代码将一个geohash编码转换为经纬度: import geohash gh = 'wx4gec' lat, lon = geohash.decode(gh) print(lat, lon) 输出结果为: 39.9041748046875 116.40739440917969 通过geohash库,可以方便地进行地理位置的编码和解码操作,适用于需要处理地理位置信息的应用场景。