hash 算法

作者: 夜千寻墨 | 来源:发表于2018-06-26 19:36 被阅读47次

    什么是 hash 算法

    散列方法的主要思想是根据结点的关键码值来确定其存储地址:以关键码值K为自变量,通过一定的函数关系h(K)(称为散列函数),计算出对应的函数值来,把这个值解释为结点的存储地址,将结点存入到此存储单元中。检索时,用同样的方法计算地址,然后到相应的单元里去取要找的结点。通过散列方法可以对结点进行快速检索。散列(hash,也称“哈希”)是一种重要的存储方式,也是一种常见的检索方法。

    散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。

    Hash算法有什么特点

    一个优秀的 hash 算法,将能实现:

    • 正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。

    • 逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。

    • 输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。

    • 冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

    但在不同的使用场景中,如数据结构和安全领域里,其中对某一些特点会有所侧重。

    几种常见的hash算法

    • MD5
    • SHA-1
    • SHA-2
    • SHA-256
    • SHA-512
    • SHA-3
    • RIPEMD-160

    MD5 加密使用

    func Md5(data string)  {
    
        fmt.Println("-----------Md5-----------")
        mes := []byte(data)
    
        // 1. 使用系统的包实现
        // 密文为16进制的数字 16 *8 = 128位
        by := md5.Sum(mes)
        fmt.Printf("%x\n", by)
    
        // 2. 第二种写法
        m := md5.New()
        m.Write(mes)
        //将字节数组转换成字符串
        s2:= hex.EncodeToString(m.Sum(nil))
        fmt.Println(s2)
    }
    

    Sha256加密使用

    func Sha256(data string)  {
    
        fmt.Println("--------sha256----------")
    
        // 32字节 通用在公链中 32 * 8 = 256 位
        // 2. 第一种写法
        by := sha256.Sum256([]byte(data))
        s := fmt.Sprintf("%x", by)
        fmt.Println(s)
    
      // 2. 第二种写法
        m := sha256.New()
        m.Write([]byte(data))
        s2 := hex.EncodeToString(m.Sum(nil))
        fmt.Println(s2)
    
    
        //对文件中的数据进行加密
        file, _ := os.Open("test.txt")
        h := sha256.New()
        //将file copy到 h中
        io.Copy(h, file)
        resu := h.Sum(nil)
    
        fmt.Println(hex.EncodeToString(resu))
    }
    

    rpemd160加密使用

    //需要用到三方库 crypto
    func Ripem160(data string)  {
    
        fmt.Println("-------Ripem160--------")
        rip := ripemd160.New()
        rip.Write([]byte(data))
        res := hex.EncodeToString(rip.Sum(nil))
    
        fmt.Println(res)
    }
    

    md5 实现原理

    对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

    1. 填充:如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);

    2. 记录信息长度:用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N*512+448+64=(N+1)*512位。

    3. 装入标准的幻数(四个整数):标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是(A=0X67452301,B=0XEFCDAB89,C=0X98BADCFE,D=0X10325476)

    4. 四轮循环运算

    sha256 实现原理

    SHA-256 算法输入报文的最大长度不超过2^64 bit,输入按512-bit 分组进行处理,产生的输出是一个256-bit 的报文摘要。

    • 附加填充比特:对报文进行填充使报文长度与448 模512 同余(长度=448 mod 512),填充的比特数范围是1 到512,填充比特串的最高位为1,其余位为0。就是先在报文后面加一个 1,再加很多个0,直到长度 满足 mod 512=448.为什么是448,因为448+64=512. 第二步会加上一个 64bit的 原始报文的 长度信息。

    • 附加长度值 将用64-bit 表示的初始报文(填充前)的位长度附加在步骤1 的结果后(低位字节优先)。

    • 初始化缓存:使用一个256-bit 的缓存来存放该散列函数的中间及最终结果。

    • 处理512-bit(16 个字)报文分组序列:该算法使用了六种基本逻辑函数,由64步迭代运算组成。每步都以256-bit 缓存值ABCDEFGH 为输入,然后更新缓存内容。 每步使用一个32-bit 常数值Kt 和一个32-bit Wt。

    相关文章

      网友评论

        本文标题:hash 算法

        本文链接:https://www.haomeiwen.com/subject/aynmyftx.html