摘要、加密算法、校验
哈希算法
将任意长度的二进制值串映射为固定长度的二进制值串。
哈希算法在理论上是做不到完全不冲突的,无法做到零冲突。不过,哈希值越长,散列冲突的概率越低。所以,在有限的时间和资源下,哈希算法是很难破解的。
安全加密
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签名
私钥加密,公钥解密。因为私钥不公开,只要解密后的信息确认是正确的,就能确定是本人发送。
因为公钥是公开的,谁都可以解密信息。如果只想向某人发送信息,可以用某人的公钥二次加密,保证只有某人能解开。

浙公网安备 33010602011771号