摘要、加密算法、校验

哈希算法

将任意长度的二进制值串映射为固定长度的二进制值串。
哈希算法在理论上是做不到完全不冲突的,无法做到零冲突。不过,哈希值越长,散列冲突的概率越低。所以,在有限的时间和资源下,哈希算法是很难破解的。

安全加密

MD5,Message Digest ALgorithm,消息摘要算法;
SHA,Secure Hash Algorithm,安全散列算法;
DES,Data Encryption Standard,数据加密标准;
AES,Advanced Encryption Standard,高级加密标准;

唯一标识

摘要。海量图库中,搜索一张图是否存在。
可以给每一张图片取一个唯一标识(摘要),和相应的图片路径信息,都存储在散列表中。
在散列表中查找是否存在唯一标识。若存在,再根据相应的图片路径,与要搜索的图片做全量的比对,看是否完全一样。如果不一样,说明两张图尽管唯一标识相同,但并不是相同的图片。

数据校验

校验文件的安全、正确、完整。比如分块下载。
当文件块下载完成后计算哈希值,然后和种子文件中保存的哈希值进行比对。如果不同,说明这个文件块不完整或者被篡改了,需要重新下载。

散列函数

散列表。不关心冲突、反向解密等,更加关注散列后的值是否能平均分布,即一组数据能否均匀地散列在各个槽中;追求算法高效。

负载均衡

同一个客户端上,在一次会话中所有的请求都路由到同一个服务器上。
对客户端IP地址或会话ID获取哈希值,然后与服务器列表的大小进行取模运算,最终得到的值就是被路由到的服务器编号。这样,就可以把同一个IP过来的所有请求,都路由到同一个后端服务器上。

数据分片

搜索关键词 统计

假如有1T以上大小的日志文件,记录了用户搜索的关键词,如何快速统计出每个关键词被搜索的次数?
可以对数据进行分片,采用多台机器处理的方法,来提高处理速度。比如用n台机器并行处理,分别依次读取每个搜索关键词,计算哈希值,再n取模,得到机器编号。这样,同一个关键词会被分配到同一个机器上。这个处理过程也是MapReduce的基本设计思想。

判断图片是否在库中

假设有1亿张图片,构建散列表明显会超出单台机器的内存上限。具体需要几台机器,可以大致估算一下。
假设一台机器的内存大小为8G,散列表的装载因子为0.75,散列表中每个数据单元占用字节152 byte(每个数据单元包含两个信息:哈希值和图片文件路径,如果用链表法来解决冲突,还需要存储指针,占用8 B;若是MD5计算哈希值,长度为128 bit=16 B;文件路径长度的上限是256 B,假设平均长度是128 B;共总152)。那么一台机器可以构造散列表的大小约为4000W(8G*0.75/152),即可以给4000w张图片构建散列表。如果要对1亿张图片构建索引,需要大约3台机器。
计算当前图片的哈希值,再n取模,得到的值k,即为编号k的机器,就需要去机器k构建的散列表中查找。后续判断逻辑与上面的类似。

分布式存储

一致性哈希算法,借助哈希环和虚拟节点,可以实现快速扩容缩容,又不会导致数据偏移。

摘要

MD5

using System;
using System.IO;
using System.Security.Cryptography;
public static class Md5Helper
{
    public static string GetMD5(string filePath)
    {
        using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            return GetMD5(fs);
        }
    }
    public static string GetMD5(Stream fileData)
    {
        string result = string.Empty;
        MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider();
        byte[] buffer = md5Provider.ComputeHash(fileData);
        string resule = BitConverter.ToString(buffer);
        result = resule.Replace("-", "");
        md5Provider.Dispose();

        return result.ToLower();
    }
}

SHA

using System;
using System.Security.Cryptography;
using System.Text;
public static class ShaHelper
{
    /// <summary>
    /// SHA1编码
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string Sha1Encrypt(string str)
    {
        var data = Encoding.UTF8.GetBytes(str);
        using (var sha1 = SHA1.Create())
        {
            var encryptData = sha1.ComputeHash(data);
            var rslt = BitConverter.ToString(encryptData);
            return rslt;
        }
    }
}

加密

对称加密

AES

/// <summary>
/// 对称加密帮助类
/// </summary>
public static class AesHelper
{
    private static readonly string _privateKey = "wesson121234567890987654ertyuiok";
    private static readonly Encoding _encoding = Encoding.UTF8;
    /// <summary>
    /// AES 加密
    /// </summary>
    /// <param name="str">待加密字符串</param>
    /// <returns></returns>
    public static string Encrypt(string str)
    {
        if (string.IsNullOrEmpty(str))
        {
            return null;
        }
        try
        {
            byte[] byteArr = _encoding.GetBytes(str);
            RijndaelManaged rm = new RijndaelManaged
            {
                Key = _encoding.GetBytes(_privateKey),
                BlockSize = 128,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };

            ICryptoTransform transform = rm.CreateEncryptor();
            byte[] rslt = transform.TransformFinalBlock(byteArr, 0, byteArr.Length);
            rm.Clear();

            return Convert.ToBase64String(rslt, 0, rslt.Length);
            //return ToHexString(rslt);
        }
        catch (Exception ex)
        {
            string err = e.Message;
        }
        return null;
    }

    /// <summary>
    /// AES 解密
    /// </summary>
    /// <param name="str">待解密字符串</param>
    /// <returns></returns>
    public static string Decrypt(string str)
    {
        if (string.IsNullOrEmpty(str))
        {
            return null;
        }
        try
        {
            byte[] byteArr = Convert.FromBase64String(str);
            //byte[] byteArr = HexString2Byte(str);
            var rm = new RijndaelManaged
            {
                Key = _encoding.GetBytes(_privateKey),
                BlockSize = 128,
                Mode = CipherMode.ECB,
                Padding = PaddingMode.PKCS7
            };

            ICryptoTransform transform = rm.CreateDecryptor();
            byte[] rslt = transform.TransformFinalBlock(byteArr, 0, byteArr.Length);
            rm.Clear();

            return _encoding.GetString(rslt);
        }
        catch (Exception ex)
        {
            string err = e.Message;
        }
        return null;
    }
}

非对称加密

RSA加密

RSA使用了不同的钥匙,公钥和私钥。
公钥加密信息,私钥解密信息。

数字签名

RSA签名

私钥加密,公钥解密。因为私钥不公开,只要解密后的信息确认是正确的,就能确定是本人发送。
因为公钥是公开的,谁都可以解密信息。如果只想向某人发送信息,可以用某人的公钥二次加密,保证只有某人能解开。

posted @ 2020-01-08 10:03  wesson2019  阅读(332)  评论(0)    收藏  举报