精华内容
下载资源
问答
  • 哈希算法用途

    千次阅读 2019-05-25 21:35:44
    什么是哈希算法 一说到哈希算法, 我瞬间就想到了哈希函数、哈希表, 其实他们并不是一回事. 简单来说, 哈希算法就是将任意长度的字符串通过计算转换为固定长度的字符串, 不对, 不光字符串, 应该说是将任意长度的二...

    什么是哈希算法

    一说到哈希算法, 我瞬间就想到了哈希函数、哈希表, 其实他们并不是一回事.

    简单来说, 哈希算法就是将任意长度的字符串通过计算转换为固定长度的字符串, 不对, 不光字符串, 应该说是将任意长度的二进制串转换为固定长度的二进制串, 这个转换的过程就是哈希算法.

    既然将任意长度的字符串转换成固定长度的, 那么冲突就不可避免了, 比如将0-100所有的数字, 映射到0-10这十个数字上, 难免会发生冲突. 一般来说, 计算得出的哈希值越长, 冲突的概率就越低, 比如说, 计算过后, 哈希值为16个字节, 也就是128位, 那么就有2^128个不同的哈希值, 发生哈希冲突的概率为(1/2)^128, 这个概率可以说很低了.

    以MD5为例, 以下是经过MD5转换后的值:

    朋友你好: 677fe16950241e74ef632efb2b9f92a7

    朋友你好!: 6efa551df87d9de987f17be4e73eb720

    可以看到, 哪怕仅仅差了一个感叹号, 计算后的值也是天壤之别, 所以很多网站上下载文件的同时还提供md5值, 现在能够理解了吧, 你将下载后的文件通过md5算法进行计算, 得到的字符串如果和网站给定的不相同, 说明文件被修改过了.

    当然, 哈希算法不仅仅只有md5这一种, 以用途来分析哈希算法, 就不说哈希算法的原理了, 因为我不会.

    1. 数据校验

    上面说到的md5就是其中的一个, 好像还有一个什么SHA, 不过我不知道, 也就不展开探讨了.

    md5可以将一个文件经过计算转换成一个指定长度的字符串, 可以防止文件被篡改, 但是通过加密后的字符串很难逆向推出原文.

    前面那个例子可以看到, 即使文件被修改了一点点, 也会导致计算后的值发生很大变换.

    2.唯一标识

    比如说, 现在有十万个文件, 给你一个文件, 要你在这十万个文件中查找是否存在. 一个很笨的办法就是把每一文件都拿出来, 然后按照二进制串一一进行对比. 但是这个操作注定是比较费时的.

    可以用哈希算法对文件进行计算, 然后比较哈希值是否相同. 因为存在哈希冲突的情况, 你可以在相同哈希值的文件再进行二进制串比较.

    3.哈希表

    在哈希表中使用哈希函数已经并不陌生了, 不再赘述.

    4.负载均衡

    比如说, 现在又多台服务器, 来了一个请求, 如何确定这个请求应该路由到哪个路由器呢?当然, 必须确保相同的请求经过路由到达同一个服务器. 一种办法就是保存一张路由关系的表, 比如客户端IP和服务器编号的映射, 但是如果客户端很多, 势必查找的时间会很长. 这时, 可以将客户端的唯一标识信息(如:IP、username等)进行哈希计算, 然后与服务器个数取模, 得到的就是服务器的编号.

    5.分布式存储

    当我们有大量数据时, 一般会选择将数据存储到多个服务器, 为了提高读取与写入的速度嘛. 决定将文件存储到哪台服务器, 就可以通过哈希算法取模的操作来得到.

    但是, 如果数据多了, 要增加服务器了, 问题就来了, 比如原来是10台服务器, 现在变成15台了, 那么原来哈希值为16的文件被分配到编号6的服务器, 现在被分配到编号1的服务器, 也就意味着所有文件都要重新计算哈希值并重新非陪服务器进行存储. 一致性哈希就是这个用途, 可以查找我的历史文章.

    暂时我能想到的就只有这些, 当然, 哈希算法的用途还有很多, git中的commit id等, 但是我不太了解, 就假装没有吧, 嘿嘿


    有时对用户的密码进行MD5加密再保存, 确实要比明文保存好的多. 但是, 你以为通过哈希算法进行加密就万事大吉了么? 不好意思, 并不能, 像前面提到的MD5就已经号称别破解了.

    比如, 你将用户的密码进行MD5加密后进行保存, 若有心人拿到你的数据库数据, 虽然得到的是加密后的密码, 但是只要准备一个常用密码的字典, 将字典中的密码进行加密后与数据库保存的数据进行比较, 如果相同, 基本上就可以确定了.

    我感觉可以对密码进行双层加密, 也就是使用两个不同的加密算法, 一个算法的输出作为另一个的输入, 增大一些破解的难度吧.

    再见!!!

    展开全文
  • 一、一致性哈希算法

    2020-07-05 10:57:53
    1 一致性哈希算法用途 2 一致性哈希算法介绍 3 一致性哈希算法实现 3.1 排序算法+二分查找 3.2 直接遍历 3.3 二叉查找树 4 TreeMap实现一致性哈希 4.1 红黑树介绍 4.2 哈希再计算 4.3 一致性哈希算法代码...

    目录

     

    1 一致性哈希算法用途

    2 一致性哈希算法介绍

    3 一致性哈希算法实现

    3.1 排序算法+二分查找

    3.2 直接遍历

    3.3 二叉查找树

    4 TreeMap实现一致性哈希

    4.1 红黑树介绍

    4.2 哈希再计算

    4.3 一致性哈希算法代码实现

    4.4 一致性哈希算法优化(虚拟节点)


    1 一致性哈希算法用途

    一致性哈希是解决上线、下线后相同的请求尽可能的命中原来服务器的问题。
    假如我们自己设计了一个高可用缓存系统,可以集群部署,那么我们每个节点上应该怎样分配数据呢?
    假如说我们存放一个k-v数据,这个数据需要怎么确定存放节点?常用的方式是用key的哈希值对服务器节点取模,这样实现比较简单,但是带来的问题就是缓存系统上线、下线节点后原来节点缓存的数据命中率打打大大降低。
    三个节点的路由表
    哈希值    0    1    2    3    4    5    6    7    8    9    10    11    12    13    14
    路由        0    1    2    0    1    2    0    1    2    0    1       2      0     1      2
    四个节点的路由表
    哈希值    0    1    2    3    4    5    6    7    8    9    10    11    12    13    14
    路由        0    1    2    3    0    1    2    3    0    1     2      3      0      1      2
    可以看到只有6个哈希值在可以路要到原来的服务器,其余的缓存都不能命中。这样带来的直接后果是
    1 可能可能会带来类似缓存雪崩的影响。缓存雪崩是指缓存数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机。
    2 节点中大量无法命中的数据过期之前还在占用内存。

    2 一致性哈希算法介绍

    为了更好地提升缓存系统的伸缩性需要设计一个可靠的一致性哈希算法。
    一致性哈希算法是构建一个哈希环来实现key到节点的映射。我们定义一个哈希环如下结构(0,1,2三个节点哈希值分别是0,5,10),每个节点是每个缓存系统的哈希值
    0->5->10->0
    路由规则是每个key落到刚好比它哈希值大的节点上。如果这个key大于环上所有的哈希值那么就落在最小的哈希节点
    三个节点的路由表
    哈希值    0    1    2    3    4    5    6    7    8    9    10    11    12    13    14
    路由        1    1    1    1    1    2    2    2    2    2    0      0      0      0      0
    这个时候我们增加了一个节点,哈希值是12,那么新的哈希环如下
    0->5->10->12->0
    四个节点的路由表
    哈希值    0    1    2    3    4    5    6    7    8    9    10    11    12    13    14
    路由        1    1    1    1    1    2    2    2    2    2    3      3      0      0      0
    这个时候我们看到只有两个哈希值没有路由到原来的节点,服务扩容后只会影响新增服务下一个节点的缓存路由,很好的解决了取模路由暴露的两个两个问题。

    3 一致性哈希算法实现

    3.1 排序算法+二分查找

    最优的排序算法时间复杂度是O(NlogN),二分查找算法时间复杂度是O(logN),所以这种方式的时间复杂度取决于耗时较长的排序算法,即O(NlogN)

    3.2 直接遍历

    这种方式比较简单,时间复杂度是O(N)

    3.3 二叉查找树

    二叉查找树的优点是查找效率高,时间复杂度是Olog(N),缺点是建树过程比较耗性能。不过考虑到服务上下线场景比较有限,这个缺点可以忽略,下面我们就以二叉查找树为例来实现一致性哈希算法

    4 TreeMap实现一致性哈希

    4.1 红黑树介绍

    满足以下特征的树就是红黑树
    1. 节点是红色或者黑色
    2. 根节点是黑色
    3. 每个叶子的节点都是黑色的空节点(NULL)
    4. 每个红色节点的两个子节点都是黑色的。
    5. 从任意节点到其每个叶子的所有路径都包含相同的黑色节点。
    这些约束强制了红黑树的关键性质: 从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。


    TreeMap就是红黑树的实现。

    4.2 哈希再计算

    我们看一下调用String默认的哈希算法计算节点ip的哈希值
    127.0.0.1:8080->127.0.0.1:8084

    @Test
    public void testStringHash() {
        // 5个server服务器
        for (int i = 0; i < 5; i ++) {
            String server = "127.0.0.1:808" + i;
            System.out.println(server + "->" + server.hashCode());
        }
    }

    输出:
    127.0.0.1:8080->-35736627
    127.0.0.1:8081->-35736626
    127.0.0.1:8082->-35736625
    127.0.0.1:8083->-35736624
    127.0.0.1:8084->-35736623
    可以看到这种方式计算的结果,哈希值根本散不开
    重新计算Hash值的算法有很多,可以参考https://blog.csdn.net/whut_gyx/article/details/39002191了解下
    这里我们采用散列效果和性能都不错的FNV1_32_HASH算法

    private int fnv32Hash(String str) {
        final int p = 16777619;
        int hash = -2128831035;
        for (int i = 0; i < str.length(); i++) {
            hash = (hash ^ str.charAt(i)) * p;
        }
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
    
        // 如果算出来的值为负数则取其绝对值
        if (hash < 0) {
            hash = Math.abs(hash);
        }
        return hash;
    }

    测试代码

    @Test
    public void testFnv32Hash() {
        // 5个server服务器
        for (int i = 0; i < 5; i ++) {
            String server = "127.0.0.1:808" + i;
            System.out.println(server + "->" + fnv32Hash(server));
        }
    }

    输出:
    127.0.0.1:8080->1617490351
    127.0.0.1:8081->674407738
    127.0.0.1:8082->1511613106
    127.0.0.1:8083->1255419186
    127.0.0.1:8084->265259256
    可以看到散列效果还是不错的

    4.3 一致性哈希算法代码实现

    // key list
    private List<String> keyList;
    
    // 缓存服务器ip集合
    private List<String> serverList;
    
    // 缓存服务器构建的二叉树
    private SortedMap<Integer, String> sortedMap = new TreeMap<>();
    @Before
    public void init() {
        // 100个key
        keyList = new ArrayList<>();
        for (int i = 0; i < 100; i ++) {
            keyList.add("key" + i);
        }
    
        // 5个server服务器
        serverList = new ArrayList<>();
        for (int i = 0; i < 5; i ++) {
            serverList.add("127.0.0.1:808" + i);
        }
    }
    
    // 获取key路由到的服务器
    private String getServer(String key) {
        // 得到带路由的结点的Hash值
        int hash = fnv32Hash(key);
        // 得到大于该Hash值的所有Map
        SortedMap<Integer, String> subMap = sortedMap.tailMap(hash);
        if (subMap.size() <= 0) {
            subMap = sortedMap;
        }
        // 第一个Key就是顺时针过去离node最近的那个结点
        Integer i = subMap.firstKey();
        // 返回对应的服务器名称
        return subMap.get(i);
    
    }
    
    
    private int fnv32Hash(String str) {
        final int p = 16777619;
        int hash = -2128831035;
        for (int i = 0; i < str.length(); i++) {
            hash = (hash ^ str.charAt(i)) * p;
        }
        hash += hash << 13;
        hash ^= hash >> 7;
        hash += hash << 3;
        hash ^= hash >> 17;
        hash += hash << 5;
    
        // 如果算出来的值为负数则取其绝对值
        if (hash < 0) {
            hash = Math.abs(hash);
        }
        return hash;
    }

    测试代码:

    @Test
    public void testConsistentHash() {
        for (String server : serverList) {
            int hash = fnv32Hash(server);
            System.out.println("[" + server + "]加入集合中, 其Hash值为" + hash);
            sortedMap.put(hash, server);
        }
        Map<String, List<String>> map = new HashMap<>();
        for (String key : keyList) {
            String server = getServer(key);
            List<String> list = map.get(server);
            if (Objects.isNull(list)) {
                list = new ArrayList<>();
                map.put(server, list);
            }
            list.add(key);
        }
        map.forEach((k, v) -> System.out.println(k + "->" + v.size() + ":" + v));
    }

    输出:
    [127.0.0.1:8080]加入集合中, 其Hash值为1617490351
    [127.0.0.1:8081]加入集合中, 其Hash值为674407738
    [127.0.0.1:8082]加入集合中, 其Hash值为1511613106
    [127.0.0.1:8083]加入集合中, 其Hash值为1255419186
    [127.0.0.1:8084]加入集合中, 其Hash值为265259256
    127.0.0.1:8081->12:[key13, key19, key30, key49, key61, key63, key64, key70, key72, key92, key95, key98]
    127.0.0.1:8082->11:[key0, key10, key21, key34, key39, key45, key51, key60, key81, key86, key96]
    127.0.0.1:8080->8:[key4, key14, key43, key44, key56, key84, key87, key89]
    127.0.0.1:8083->27:[key6, key7, key9, key11, key20, key25, key26, key27, key28, key33, key40, key41, key42, key46, key47, key52, key55, key65, key67, key71, key74, key77, key78, key90, key91, key93, key97]
    127.0.0.1:8084->42:[key1, key2, key3, key5, key8, key12, key15, key16, key17, key18, key22, key23, key24, key29, key31, key32, key35, key36, key37, key38, key48, key50, key53, key54, key57, key58, key59, key62, key66, key68, key69, key73, key75, key76, key79, key80, key82, key83, key85, key88, key94, key99]

    4.4 一致性哈希算法优化(虚拟节点)

    上述代码一致性哈希算法我们可以看到每个key可以被正确路由到对应的节点,但是有另一个问题,分配不均。我们看到分配最少缓存的节点上只有8个缓存,最多缓存节点上有42个缓存
    解决这个问题的办法是引入虚拟节点,其工作原理是:将一个物理节点拆分为多个虚拟节点,并且同一个物理节点的虚拟节点尽量均匀分布在Hash环上。采取这样的方式,就可以有效地解决增加或减少节点时候的负载不均衡的问题。
    带有虚拟节点的一致性哈希算法实现

    @Test
    public void testConsistentVirtualHash() {
        List<String> virtualServerList = new ArrayList<>();
        // 每个server虚拟5个地址
        int virtualServerCount = 5;
        for (String server: serverList) {
            for (int i = 0; i < virtualServerCount; i ++) {
                String virtualServer = server + "@VN" + i;
                virtualServerList.add(virtualServer);
            }
        }
        for (String virtualServer : virtualServerList) {
            int hash = fnv32Hash(virtualServer);
            System.out.println("[" + virtualServer + "]加入集合中, 其Hash值为" + hash);
            sortedMap.put(hash, virtualServer);
        }
    
        Map<String, List<String>> map = new HashMap<>();
        for (String key : keyList) {
            String virtualServer = getServer(key);
            // 解析出真正的ip
            String realServer = virtualServer.split("@")[0];
            List<String> list = map.get(realServer);
            if (Objects.isNull(list)) {
                list = new ArrayList<>();
                map.put(realServer, list);
            }
            list.add(key);
        }
        map.forEach((k, v) -> System.out.println(k + "->" + v.size() + ":" + v));
    }

    输出
    [127.0.0.1:8080@VN0]加入集合中, 其Hash值为1653752734
    [127.0.0.1:8080@VN1]加入集合中, 其Hash值为2045770422
    [127.0.0.1:8080@VN2]加入集合中, 其Hash值为642460142
    [127.0.0.1:8080@VN3]加入集合中, 其Hash值为2064903931
    [127.0.0.1:8080@VN4]加入集合中, 其Hash值为134338595
    [127.0.0.1:8081@VN0]加入集合中, 其Hash值为1207025989
    [127.0.0.1:8081@VN1]加入集合中, 其Hash值为1416458113
    [127.0.0.1:8081@VN2]加入集合中, 其Hash值为2109124764
    [127.0.0.1:8081@VN3]加入集合中, 其Hash值为487588720
    [127.0.0.1:8081@VN4]加入集合中, 其Hash值为887324084
    [127.0.0.1:8082@VN0]加入集合中, 其Hash值为27662755
    [127.0.0.1:8082@VN1]加入集合中, 其Hash值为1353238534
    [127.0.0.1:8082@VN2]加入集合中, 其Hash值为1234344991
    [127.0.0.1:8082@VN3]加入集合中, 其Hash值为1502278984
    [127.0.0.1:8082@VN4]加入集合中, 其Hash值为1362517544
    [127.0.0.1:8083@VN0]加入集合中, 其Hash值为1128722563
    [127.0.0.1:8083@VN1]加入集合中, 其Hash值为1998095489
    [127.0.0.1:8083@VN2]加入集合中, 其Hash值为2077514034
    [127.0.0.1:8083@VN3]加入集合中, 其Hash值为1266869294
    [127.0.0.1:8083@VN4]加入集合中, 其Hash值为842010729
    [127.0.0.1:8084@VN0]加入集合中, 其Hash值为263233063
    [127.0.0.1:8084@VN1]加入集合中, 其Hash值为1695356940
    [127.0.0.1:8084@VN2]加入集合中, 其Hash值为956902
    [127.0.0.1:8084@VN3]加入集合中, 其Hash值为2050272550
    [127.0.0.1:8084@VN4]加入集合中, 其Hash值为1840275863
    127.0.0.1:8081->11:[key7, key9, key42, key47, key59, key61, key64, key67, key70, key71, key99]
    127.0.0.1:8082->8:[key0, key21, key39, key45, key60, key79, key81, key96]
    127.0.0.1:8080->31:[key3, key4, key10, key12, key13, key14, key19, key22, key23, key24, key30, key31, key34, key43, key44, key49, key50, key51, key54, key56, key57, key63, key66, key72, key73, key82, key84, key86, key87, key89, key98]
    127.0.0.1:8083->30:[key5, key6, key8, key11, key17, key18, key20, key25, key26, key27, key28, key33, key38, key40, key41, key46, key52, key55, key65, key74, key77, key78, key85, key90, key91, key92, key93, key94, key95, key97]
    127.0.0.1:8084->20:[key1, key2, key15, key16, key29, key32, key35, key36, key37, key48, key53, key58, key62, key68, key69, key75, key76, key80, key83, key88]
    可以看到我们虚拟5个节点后分配最少缓存的节点上只有8个缓存,最多缓存节点上有31个缓存,提高了缓存分配均衡性

    展开全文
  • 哈希 算法

    2021-05-31 18:52:14
    哈希算法 基本概念:哈希算法是把一个无限的输入集合映射到一个有限的输出集合(散列值) 哈希算法最重要的特点就是: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。 哈希算法的目的: 就是为了...

    哈希算法
    基本概念:哈希算法是把一个无限的输入集合映射到一个有限的输出集合(散列值)
    哈希算法最重要的特点就是:
    相同的输入一定得到相同的输出;
    不同的输入大概率得到不同的输出。

    哈希算法的目的:
    就是为了验证原始数据是否被篡改。(哈希碰撞)
    哈希碰撞
    哈希碰撞是指,两个不同的输入得到了相同的输出:

    哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。哈希碰撞肯定是概率发生的,所以衡量一个哈希算法是否优秀与安全,就是这个碰撞概率,所以这个碰撞概率越低越优秀。
    你可以定义自己的哈希算法:

    coding:utf-8

    自定义哈希函数

    def my_hash(x):
    return (x % 7) ^ 9

    print(my_hash(1))
    print(my_hash(2))
    print(my_hash(3))
    print(my_hash(4))
    但是你会发现你定义的这个简单哈希规律性很强,如果我很容易碰撞且很容易猜测属出,所以衡量一个哈希算法是否优秀与安全要满足:
    1、发生碰撞概率底
    2、不容易推断输出结果

    常用的哈希算法:

    算法 输出长度(位) 输出长度(字节)
    MD5 128 bits 16 bytes
    SHA-1 160 bits 20 bytes
    RipeMD-160 160 bits 20 bytes
    SHA-256 256 bits 32 bytes
    SHA-512 512 bits 64 bytes

    Python 3内置hash()函数
    在运行hash()函数时你会发现了一个现象:相同字符串在同一次运行时的哈希值是相同的,但是不同次运行的哈希值不同。这是由于Python的字符串hash算法有一个启动时随机生成secret prefix/suffix的机制,存在随机化现象:对同一个字符串输入,不同解释器进程得到的hash结果可能不同。因此当需要做可重现可跨进程保持一致性的hash,需要用到hashlib模块

    hashlib提供了常见的摘要算法,如MD5,SHA1

    哈希算法的用途
    因为相同的输入永远会得到相同的输出的性质,一般有如下用途
    1、验证输入是否被篡改。
    2、存储用户口令(注意防止彩虹表攻击。)
    比如你在下载一个软件:

    你会看到显示的哈希,这个就可以用做比对你下载的软件是否被串改,你可以用官网提示的算法,在本地计算下然后与之比对。
    哈希算法的另一个重要用途是存储用户口令。如果直接将用户的原始口令存放到数据库中,会产生极大的安全风险:
    数据库管理员能够看到用户明文口令;
    数据库数据一旦泄漏,黑客即可获取用户明文口令。
    比如Django的session表内容。
    彩虹表攻击
    彩虹表,什么是彩虹表?
    因为相同的输入永远会得到相同的输出的性质,所以在我们猜到hash算法后我可以提前计算常用口令的hash,然后建立一一对应的表,然后用hash值反推常用的口令。

    常用口令 MD5
    hello123 f30aa7a662c728b7407c54ae6bfd27d1
    12345678 25d55ad283aa400af464c76d713c07ad
    passw0rd bed128365216c019988915ed3add75fb
    19700101 570da6d5277a646f6552b8832012f5dc
    … …
    20201231 6879c0ae9117b50074ce0a0d4c843060
    这个表就是彩虹表,所以不要用生日作为密码。
    如何防止呢?就是加盐,比如你设置coke和session值时额外添加一个随机数,这样就能达到无法反推的目的。

    展开全文
  • 哈希算法

    2019-04-03 14:18:12
    什么是哈希算法哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。它的原理其实很简单,就是把一段交易信息转换成一个固定长度的字符串。 这串字符串...

    原文:https://blog.csdn.net/xinshengdaxue000/article/details/80545146 

    什么是哈希算法?

    哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。它的原理其实很简单,就是把一段交易信息转换成一个固定长度的字符串。

    这串字符串具有一些特点:
    1. 信息相同,字符串也相同。

    2. 信息相似不会影响字符串相同。

    3. 可以生成无数的信息,但是字符串的种类是一定的,所以是不可逆的。

    让我们举个例子理解一下:如果我们要搜一张图片,在没有人工标注的情况下,于巨大的图库中想要以图搜图是一件及其庞大而又困难的工作量。

    可是在训练集上,通过哈希算法,可以得到一系列哈希函数,通过这些函数,可以将每一张图片转化成一串0~1的编码。

    比较神奇的是,编码串相似的图片对应的语义也是相似的。

    这就是简单的哈希算法在生活中的简单应用。

    哈希算法有什么用途?


    哈希算法可以检验信息是否是相同的,这样的优势可以节省重复文件传送的时间。

    举一个生活中很平常的例子,我们在生活工作中会使用一些软件给别人传送文件数据,如果有人传送了一份文件给一个人,然后又有一个人传送了相同的文件给了另外一个人,那么这个社交软件在第二次传送文件的时候会对比两次传送的哈希值,发现是相同的,该软件就不会再次上传文件给服务器了。

    除此之外,哈希算法还可以检验信息的拥有者是否真实。

    比如,我们在一个网站注册一个账号,如果网站把密码保存起来,那这个网站不论有多安全,也会有被盗取的风险。但是如果用保存密码的哈希值代替保存密码,就没有这个风险了,因为哈希值加密过程是不不可逆的。

    哈希算法会不会被破解?


    从理论上说,哈希值是可以被获得的,但是对应的用户密码很难获得。


    假设一个网站被攻破,黑客获得了哈希值,但仅仅只有哈希值还不能登录网站,他还必须算出相应的账号密码。

    计算密码的工作量是非常庞大且繁琐的,严格来讲,密码是有可能被破译的,但破译成本太大,被成功破译的几率很小,所以基本是不用担心密码泄露的。

    当然,黑客们还可以采用一种物理方法,那就是猜密码。他可以随机一个一个的试密码,如果猜的密码算出的哈希值正好与真正的密码哈希值相同,那么就说明这个密码猜对了。

    密码的长度越长,密码越复杂,就越难以猜正确。如果有一种方法能够提高猜中密码的可能,那么可以算是哈希算法被破解了。


     

    展开全文
  • 哈希算法 有两个特点: ● 加密过程不可逆,意味着我们无法通过输出的散列数据倒推原本的明文是什么; ● 输入的明文与输出的散列数据一一对应,任何一个输入信息的变化,都必将导致最终输出的散列数据的变化。 ...
  • FNV哈希算法

    2017-02-21 22:35:42
    FNV哈希算法
  • 哈希算法的应用

    2021-07-16 21:16:19
    文章目录前言一、哈希算法是什么?二、应用一:安全加密三、应用二:唯一标识四、应用三:散列函数五、应用四:数据校验六、应用五:负载均衡总结 前言 哈希算法经常使用的场景是哈希表,也叫散列表。但是在很多 ...
  • 什么是哈希算法?哈希是一种加密算法,也称为散列函数或杂凑函数。哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者...
  • 摘要算法(哈希算法)

    2021-09-19 23:57:51
    哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。 哈希函数的主要作用不是完成数据加密与解密工作,它是用来检验数据完整性的重要技术,运算过程...
  • 哈希算法简单理解就是实现哈希函数的算法,用于将任意长度的二进制值串映射为固定长度的二进制值串,映射之后得到的二进制值就是哈希值(散列值)。 我们日常开发中最常见的哈希算法应用就是通过 md5 函数对数据...
  • 哈希算法相关梳理

    2019-02-08 09:59:51
    1.基本概念 哈希也成为“散列”:任意长度的输入,经过哈希算法变换成...不同的哈希算法,哈希值长度不同,但相同的哈希算法,哈希值长度固定。哈希值的长度越长越安全。(出现碰撞的概率越低) 2.常用的哈希算法 ...
  • 感知哈希算法

    2019-10-01 21:19:37
    其实我们利用一个算法就能达到相似的效果,其中涉及到的算法就是【感知哈希算法(Perceptual hash algorithm)】,下面就简单介绍下该算法。 感知哈希算法的原理就是给每张图片生成一个“指纹”,指纹越相似的两张...
  • python hashlib 哈希算法

    千次阅读 2019-09-28 23:03:22
    在密码学中,好的哈希算法应该满足以下两个条件:一是无法从哈希值解密原始消息;二是,更改原始消息的一个字节,哈希消息会发生非常大的变化。本篇博客主要探讨一下python标准库hashlib的使用,最后介绍一下另外两...
  • 哈希算法说明及示例

    2020-10-30 16:24:37
    定义:哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。它的原理其实很简单,就是把一段交易信息转换成一个固定长度的字符串 特点: 1. 信息相同,...
  • 4.1 哈希算法

    千次阅读 2018-09-30 14:53:11
    以哈希函数为基础构造的哈希算法,在现代密码学中扮演着重要的角色,常用于实现数据完整性和实体认证,同时也构成多种密码体制和协议的 安全保障。碰撞是与哈希函数相关的重要概念,体现着哈希函数的安全性,所谓...
  • 密码学之哈希算法

    千次阅读 2018-09-11 21:41:48
    1 哈希算法 哈希算法是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,...
  • 了解一致性哈希算法

    2019-10-09 01:12:03
    一致性哈希算法是为了解决普通哈希算法的热点问题,当使用普通哈希算法来切割数据到不同的缓存服务器时。 一旦缓存服务器的数量产生变化,客户端向缓存服务器请求相应的数据就不会命中,转而请求具体的数据库服务器...
  • 哈希算法不是仅仅应用于我们常用结构哈希表中,哈希算法是一个更加广泛的概念。将任意长度的二进制值串映射为固定长度的二进制值串,这个映射的规则就是哈希算法,而通过原始数据映射之后得到的二进制值串就是哈希值...
  • 1、一致性哈希算法及其用途 假设现在有一批数据需要均匀地分布在若干台服务器上,这批数据满足以下假定: 所有数据的访问频率一致。 数据的访问都是随机的。 不管数据规模多大,都希望数据的分布是均匀的 不断...
  • 1.哈希算法介绍 将任意长度的二进制值串映射为固定长度的二进制值串,该映射的规则就是哈希算法。 2.哈希算法满足条件 1.从哈希值不能反向推导出原始数据(哈希算法,单向哈希算法) 2.对输入数据非常...
  • 什么是哈希算法

    千次阅读 2018-05-07 18:27:19
    哈希函数,又称哈希算法,它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。 Hash算法特别的地方在于它是一种单向算法,用户可以通过Hash算法对目标信息生成一段特定长度...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,654
精华内容 7,861
关键字:

哈希算法用途