知识须要不断积累、总结和沉淀,思考和写做是成长的催化剂 这篇很轻松,没有什么费脑子的,因此解析较少,代码较多,为数很少的拿来即用篇 整个章节分布请移步 .NET开篇总括算法
序列化是把一个内存中的对象
的信息转化成一个能够持久化保存(二进制数据)
的形式,以便于保存或传输,序列化的主要做用是不一样平台之间进行通讯,经常使用的有序列化有json、xml、文件等,反序列化是将进制数据还原为对象
,内存中的对象稍纵即逝,序列化反序列化就是为了保持对象的持久化。就像用DV录像,用播放器播放同样。数据库
加密是经过对消息进行编码
,创建一种安全的交流方式
,使得只有你和你所指望的接收者可以理解。json
内置的BinaryFormatter
二进制序列化器用于将对象序列化和反序列化二进制文件。要引用System.Runtime.Serialization.Formatters.Binary。 假设咱们有如下对象浏览器
[Serializable] //必须添加序列化特性
public class Person
{
[NonSerialized]
public int Id = 1;
public string Name { get; set; }
public string Sex { get; set; }
}
复制代码
建立一个BinaryFormatter实例,调用实例Serialize方法将对象写入文件流中安全
string fileName = Path.Combine("D:\\", @"BinarySerialize.txt");//文件名称与路径
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
Person p = new Person() { Id = 1, Name = "jack", Sex = "男" };//对象
BinaryFormatter binFormat = new BinaryFormatter();//建立二进制序列化器
binFormat.Serialize(fStream, p);
}
复制代码
经过调用实例Deserialize方法把二进制文本反序列化为对象服务器
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
BinaryFormatter binFormat = new BinaryFormatter();//建立二进制序列化器
fStream.Position = 0;//重置流位置
Person p = (Person)binFormat.Deserialize(fStream);//反序列化对象
}
复制代码
但注意咱们必须在类上面标记Serializable特性
,才能序列化该对象,默认属性字段均可序列化了,固然咱们经过标记NonSerialized
能够要求某个字段不序列化,但这样反序列后该字段就会没有值(或默认值)框架
结合我们前天学到的泛型,咱们包装一下BinarySerializeHelper帮助类ide
public class BinarySerializeHelper
{
/// <summary>
/// 将对象序列化为字符串
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <returns>字符串</returns>
public static string ObjectToString<T>(T t)
{
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, t);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
return result;
}
}
/// <summary>
/// 将对象序列化为文件
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">实例</param>
/// <param name="path">存放路径</param>
public static void ObjectToFile<T>(T t, string path)
{
BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
formatter.Serialize(stream, t);
stream.Flush();
}
}
/// <summary>
/// 将字符串反序列为类型
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="s">字符串</param>
/// <returns>对象</returns>
public static T StringToObject<T>(string s) where T : class
{
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(s);
BinaryFormatter formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream(buffer))
{
T result = formatter.Deserialize(stream) as T;
return result;
}
}
/// <summary>
/// 将文件反序列化为对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="path">路径</param>
/// <returns>对象</returns>
public static T FileToObject<T>(string path) where T : class
{
using (FileStream stream = new FileStream(path, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
T result = formatter.Deserialize(stream) as T;
return result;
}
}
}
复制代码
在没有JSON(JavaScript Object Notation)以前,XML(Extensible Markup Language)做为规范,轻量的数据存储格式获得大量应用,经常使用来做为配置文件和数据传输。.NET内置了XmlSerializer
类来将对象序列化为xml,将XML反序列化为对象。 用法和上面BinaryFormatter同样,先实例化而后调用序列化、反序列化方法post
string fileName = Path.Combine("D:\\", @"XmlSerialize.txt");//文件名称与路径
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
Person p = new Person() { Id = 1, Name = "jack", Sex = "男" };//对象
XmlSerializer xmlFormat = new XmlSerializer(typeof(Person));//建立XML序列化器,须要指定对象的类型
xmlFormat.Serialize(fStream, p);
}
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(Person));//建立XML序列化器,须要指定对象的类型
fStream.Position = 0;//重置流位置
Person p = (Person)xmlFormat.Deserialize(fStream);//反序列化对象
}
复制代码
不一样的是实例化XmlSerializer时候须要指定待序列化对象的类型,并且对象无需标记Serializable特性
网站
咱们也能够像上面同样封装成泛型以共用
public class XmlSerializeHelper
{
/// <summary>
/// 将对象序列化为xml文件
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">对象</param>
/// <param name="path">xml存放路径</param>
public static void ObjectToXml<T>(T t, string path) where T : class
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
formatter.Serialize(stream, t);
}
}
/// <summary>
/// 将对象序列化为xml字符串
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">对象</param>
public static string ObjectToXml<T>(T t) where T : class
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, t);
string result = System.Text.Encoding.UTF8.GetString(stream.ToArray());
return result;
}
}
/// <summary>
/// 将xml文件反序列化为对象
/// </summary>
/// <typeparam name="T">类型</typeparam>
/// <param name="t">对象</param>
/// <param name="path">xml路径</param>
/// <returns>对象</returns>
public static T XmlToObject<T>(T t, string path) where T : class
{
XmlSerializer formatter = new XmlSerializer(typeof(T));
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
XmlReader xmlReader = new XmlTextReader(stream);
T result = formatter.Deserialize(xmlReader) as T;
return result;
}
}
}
复制代码
关于XML,在之前也被浓墨重彩的使用,.NET对其解析用到的类库在System.Xml下,包括XmlDocument,XmlElement,XmlNode等类能够实现对xml文档的彻底控制。
JSON(JavaScript Object Notation)相比较XML更加轻量,传输有效减小带宽,可读性也差很少,在互联网尤为移动互联网中获得普遍应用。.NET后面的框架配置也多基于JSON格式。
.NE提供了DataContractJsonSerializer和JavaScriptSerializer
两个类来进行JSON的转换,二者大体相同,DataContractJsonSerializer(命名空间System.Runtime.Serialization.Json)在wcf时代应用较多,你必须在DataContract和DataMember来特性标记成员。JavaScriptSerializer更多用在Web中通讯,能够序列化任何类型,包括匿名类型。这里以JavaScriptSerializer为例,简单使用一会儿。(命名空间System.Web.Script.Serialization)
此次咱们先直接封装个泛型方法,后面两个方法咱们用了比较经常使用的Newtonsoft.Json
第三方的JSON转换库
public class JsonSerializeHelper
{
#region Json
/// <summary>
/// 将对象序列化为Json字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string ObjectToString<T>(T obj)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Serialize(obj);
}
/// <summary>
/// 将Json字符串反序列化为对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <returns></returns>
public static T StringToObject<T>(string content)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Deserialize<T>(content);
}
/// <summary>
/// 使用Newtonsoft.Json序列化对象为json字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJson<T>(T obj)
{
return JsonConvert.SerializeObject(obj);
}
/// <summary>
/// 使用Newtonsoft.Json将json字符串反序列化为对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="content"></param>
/// <returns></returns>
public static T ToObject<T>(string content)
{
return JsonConvert.DeserializeObject<T>(content);
}
#endregion Json
}
复制代码
字面意思,加密解密,咱们常常须要对不想要别人轻松看见的东西加密,之因此说是不能轻松看见,由于安全都是相对的,没有绝对的安全,咱们加密只是提升别人破解的难度,劝退大多数人。 加密是经过对消息进行编码,创建一种安全的交流方式,使得只有你和你所指望的接收者可以理解。
那么怎么样才能叫安全呢?消息在接收方和发送方进行安全传递,通常要知足下面三个要点:
加密一般分为三种方式:不可逆加密、对称可逆加密和非对称可逆加密
MD5(单向散列算法)的全称是Message-Digest Algorithm 5(信息-摘要算法),经MD二、MD3和MD4发展而来。MD5算法的使用不须要支付任何版权费用。
MD5特色: 输入任意长度的信息,通过处理,输出为128位的信息(数字指纹); 不一样的输入获得的不一样的结果(惟一性); 根据128位的输出结果不可能反推出输入的信息(不可逆);
MD5是不可逆的,就是根据加密后信息得不到加密前的。
一、防止被篡改
好比一个电子文档,发送过程当中若是被篡改,则先后的md5不同 二、防止直接看到明文
好比用户密码消息,若是数据库中存储的明文,则泄漏后别人就直接登陆。用MD5加密后存储,即便泄密获得的也是加密后的,没法还原加密前的密码,但如今网上有不少MD5解密的,都是经过撞库实现,由于密码通常也就数字生日字母等组合,目前已知的MD5库已经有几百亿样本了,若是简单密码仍是容易经过撞库破解的,因此通常还会在用户密码基础上再加上一些自定义的信息后再MD5(俗称加盐)。 三、防止抵赖(数字签名)
A写了一个文件,而后在第三方认证机构备案,第三方利用MD5造成摘要信息,若是往后A抵赖不是他写的,第三方就对文件从新MD5而后与记录在册的比对。 四、急速秒传
网盘应用,记录第一次上传文件的MD5,而后别人再上传,匹配MD5,一致时就可不用上传,直接给个软链接,达到急速秒传。
如下是C#版本MD5加密
public class MD5Encrypt
{
/// <summary>
/// MD5加密,和动网上的16/32位MD5加密结果相同,
/// 使用的UTF8编码
/// </summary>
/// <param name="source">待加密字串</param>
/// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
/// <returns>加密后的字串</returns>
public static string Encrypt(string source, int length = 32)//默认参数 {
if (string.IsNullOrEmpty(source)) return string.Empty;
HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
byte[] bytes = Encoding.UTF8.GetBytes(source);//这里须要区别编码的
byte[] hashValue = provider.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
switch (length)
{
case 16://16位密文是32位密文的9到24位字符
for (int i = 4; i < 12; i++)
{
sb.Append(hashValue[i].ToString("x2"));//转换为小写的16进制
}
break;
case 32:
for (int i = 0; i < 16; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
default:
for (int i = 0; i < hashValue.Length; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
}
return sb.ToString();
}
/// <summary>
/// 获取文件的MD5摘要
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string AbstractFile(string fileName) {
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
return AbstractFile(file);
}
}
/// <summary>
/// 根据stream获取文件摘要
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string AbstractFile(Stream stream) {
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
}
复制代码
借用一下这张图。对称加密的思路很是简单,就是含有一个称为密钥(密码学中发音yao)的东西,在消息发送前使用密钥对消息进行加密,在对方收到消息以后,使用相同的密钥进行解密。加密速度快,但密钥安全是个问题
,密钥放在保密的地方。
以DES AES Blowfish为表明。DES(Data Encryption Standard),像加密狗
通常就是利用对称可逆加密
C#语言版本的DES加解密以下所示,注意密钥长度是8位
public class DesEncrypt
{
/// <summary>
/// 密钥key
/// </summary>
private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes("miyaokey");
/// <summary>
/// 偏移量 为了解决原文中有重复生成的密文中也有重复现象
/// </summary>
private static byte[] _rgbIV = ASCIIEncoding.ASCII.GetBytes("miyaokey".Insert(0, "w").Substring(0, 8));
/// <summary>
/// DES 加密
/// </summary>
/// <param name="text">须要加密的值</param>
/// <returns>加密后的结果</returns>
public static string Encrypt(string text) {
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
StreamWriter sWriter = new StreamWriter(crypStream);
sWriter.Write(text);
sWriter.Flush();
crypStream.FlushFinalBlock();
memStream.Flush();
return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
}
}
/// <summary>
/// DES解密
/// </summary>
/// <param name="encryptText"></param>
/// <returns>解密后的结果</returns>
public static string Decrypt(string encryptText) {
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
byte[] buffer = Convert.FromBase64String(encryptText);
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
crypStream.Write(buffer, 0, buffer.Length);
crypStream.FlushFinalBlock();
return ASCIIEncoding.UTF8.GetString(memStream.ToArray());
}
}
}
复制代码
非对称加密的接收者和发送者都持有两个密钥,一个是对外公开的,称为公钥,一个是自行保管的,称为私钥。非对称加密的规则是由某人A的公钥加密的消息,只能由A的私钥进行解密;由A的私钥加密的消息只能由A的公钥解密。
加密模式
。
认证模式
。由于不管加密模式,认证模式都没法同时知足加解密的三要点,而后引入了数字签名
数字签名
就是上面非对称加密的认证模式基础上作了改进,加入了像MD5的散列算法,多一条路对原始信息进行散列加密,消息仍以明文传递,最后比较接收到的消息的散列值和接受到原始消息散列值,肯定消息是否被中间篡改。但很明显,明文传递,不安全,第三方能够直接查看消息
C#版本的RSA(Rivest Shamir Ad1eman)加解密以下所示
public class RsaEncrypt
{
/// <summary>
/// 获取加密/解密对
/// 给你一个,是没法推算出另一个的
/// Encrypt Decrypt
/// </summary>
/// <returns>Encrypt Decrypt</returns>
public static KeyValuePair<string, string> GetKeyPair() {
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string publicKey = RSA.ToXmlString(false);
string privateKey = RSA.ToXmlString(true);
return new KeyValuePair<string, string>(publicKey, privateKey);
}
/// <summary>
/// 加密:内容+加密key
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <returns></returns>
public static string Encrypt(string content, string encryptKey) {
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(encryptKey);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
/// <summary>
/// 解密 内容+解密key
/// </summary>
/// <param name="content"></param>
/// <param name="decryptKey">解密key</param>
/// <returns></returns>
public static string Decrypt(string content, string decryptKey) {
byte[] dataToDecrypt = Convert.FromBase64String(content);
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(decryptKey);
byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
return ByteConverter.GetString(resultBytes);
}
/// <summary>
/// 能够合并在一块儿的,,每次产生一组新的密钥
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <param name="decryptKey">解密key</param>
/// <returns>加密后结果</returns>
private static string Encrypt(string content, out string publicKey, out string privateKey) {
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
publicKey = rsaProvider.ToXmlString(false);
privateKey = rsaProvider.ToXmlString(true);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
}
复制代码
CA(Certification Authority)证书是由CA权威机构
(国内像阿里),咱们在互联网里要信任一个东西,若是有个权威机构来背书,咱们可能更加信任。CA证书本身也能够颁发,就看你们认不认了。
上面验证了证书,而后获得百度的公钥(申请证书时提供的公钥,包含在证书中),用此百度公钥加密一个消息给服务器,服务器若是有正确的私钥解密返回正确的消息,则验证服务器是百度。确认以后,浏览器则随机提供一个加密钥,记得用百度公钥加密后传输(避免被中间截取),而后百度服务器获得这个新生成的加密钥,之后双方就经过这个加密钥加密传输数据,只有浏览器和服务器知道的。
下期见~拜了个拜拜(づ ̄3 ̄)づ╭❤~
vx:xishaobb
,互动或获取更多消息。固然这里也一直更新de,下期见,拜了个拜拜。