本文旨在科普安全相关的知识,并附一个C#实现的文件管理工具。

Hash

安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的五种安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的概率很高。这些算法之所以称作“安全”是基于以下两点(根据官方标准的描述):

HASH是根据文件的内容的数据通过逻辑运算得到的数值, 不同的文件(即使是相同的文件名)得到的HASH值是不同的, 所以HASH值就成了每一个文件的身份证。

不同HASH值的文件内容也是不相同的,相同的HASH值的文件的内容肯定是完全相同(即使文件名不同).

HASH值还有文件校验的功能,相当于文件的校验码. 所以还可以用来检查文件下载是否正确(比如我们在下载系统镜像或其它开源软件时,官网都会提供文件的HASH值,让我们通过对比HASH值来判断文件是否被修改过)。

文件的Hash值在下载文件的校验方面有很大的用途,Hash值是文件内容的通过二进制码进行一系列的变换生成出来的,即使文件名发生变化,Hash的值也不会发生改变。因此在开发的过程中一般比较两个文件是否相同都是去比较两个文件的Hash值。

MD5

英文全称Message-Digest Algorithm(消息摘要算法)

在下载一下东西时,经常在一些压缩包属性里,看到md5值。而且这个下载页面,很可能会在某一个地方,写了一句,此文件的MD5值为XXXXXXXXX。这有什么作用呢?

白话白话:md5,其实就是一中算法。可以将一个字符串,或文件,或压缩包,执行md5后,就可以生成一个固定长度为128bit的串。这个串,基本上是唯一的。

所以,有人修过压缩包后,就会生成新的串,这时就可以拿网站提供的串和新生成的串对比,如果不同,那就是被人修过过了。

更多请查看:https://zh.wikipedia.org/wiki/MD5 / http://www.weixuehao.com/archives/474

CRC

循环冗余校验(英语:Cyclic redundancy check,通称“CRC”)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种散列函數,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。由于本函数易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。此方是由W. Wesley Peterson于1961年发表

HashHelper

下面一个C#版本的工具类,主要功能是计算文件Hash,文件MD5,文件的CRC32

using System;
using System.IO;
using System.Text; /// <summary>
/// 提供用于计算指定文件哈希值的方法
/// <example>例如计算文件的MD5值:
/// <code>
/// String hashMd5=HashHelper.GetMD5("MyFile.txt");
/// </code>
/// </example>
/// <example>例如计算文件的CRC32值:
/// <code>
/// String hashCrc32 = HashHelper.GetCRC32("MyFile.txt");
/// </code>
/// </example>
/// <example>例如计算文件的SHA1值:
/// <code>
/// String hashSha1 =HashHelper.GetSHA1("MyFile.txt");
/// </code>
/// </example>
/// </summary>
public class HashHelper
{
/// <summary>
/// 计算指定文件的MD5值
/// </summary>
/// <param name="fileName">指定文件的完全限定名称</param>
/// <returns>返回值的字符串形式</returns>
public static String GetMD5(String fileName)
{
String hashMD5 = String.Empty;
//检查文件是否存在,如果文件存在则进行计算,否则返回空值
if (File.Exists(fileName))
{
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
//计算文件的MD5值
System.Security.Cryptography.MD5 calculator = System.Security.Cryptography.MD5.Create();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
//将字节数组转换成十六进制的字符串形式
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashMD5 = stringBuilder.ToString();
}//关闭文件流
}//结束计算
return hashMD5;
}//ComputeMD5 /// <summary>
/// 计算指定文件的CRC32值
/// </summary>
/// <param name="fileName">指定文件的完全限定名称</param>
/// <returns>返回值的字符串形式</returns>
public static String GetCRC32(String fileName)
{
String hashCRC32 = String.Empty;
//检查文件是否存在,如果文件存在则进行计算,否则返回空值
if (File.Exists(fileName))
{
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
//计算文件的CSC32值
Crc32 calculator = new Crc32();
Byte[] buffer = calculator.ComputeHash(fs);
calculator.Clear();
//将字节数组转换成十六进制的字符串形式
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < buffer.Length; i++)
{
stringBuilder.Append(buffer[i].ToString("x2"));
}
hashCRC32 = stringBuilder.ToString();
}//关闭文件流
}
return hashCRC32;
}//ComputeCRC32 /// <summary>
/// 获取文件的SHA1
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static String GetSHA1(String fileName)
{
String hashSHA1 = String.Empty;
//检查文件是否存在,如果文件存在则进行计算,否则返回空值
if (File.Exists(fileName))
{
using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
//计算文件的SHA1值
System.Security.Cryptography.SHA1 calculator = System.Security.Cryptography.SHA1.Create();
Byte[] buffer = calculator.ComputeHash(fileStream);
calculator.Clear();
//将字节数组转换成十六进制的字符串形式
StringBuilder stringBuilder = new StringBuilder();
for (int bufferIdx = 0; bufferIdx < buffer.Length; bufferIdx++)
{
stringBuilder.Append(buffer[bufferIdx].ToString("x2"));
}
hashSHA1 = stringBuilder.ToString(); }//关闭文件流
}
else
{
Console.Error.WriteLine("{0}文件找不到!", fileName);
}
return hashSHA1;
}//end GetSHA1
} /// <summary>
/// 提供 CRC32 算法的实现
/// </summary>
public class Crc32 : System.Security.Cryptography.HashAlgorithm
{
public const UInt32 DefaultPolynomial = 0xedb88320;
public const UInt32 DefaultSeed = 0xffffffff;
private UInt32 hash;
private UInt32 seed;
private UInt32[] table;
private static UInt32[] defaultTable;
public Crc32()
{
table = InitializeTable(DefaultPolynomial);
seed = DefaultSeed;
Initialize();
}
public Crc32(UInt32 polynomial, UInt32 seed)
{
table = InitializeTable(polynomial);
this.seed = seed;
Initialize();
}
public override void Initialize()
{
hash = seed;
}
protected override void HashCore(byte[] buffer, int start, int length)
{
hash = CalculateHash(table, hash, buffer, start, length);
}
protected override byte[] HashFinal()
{
byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
this.HashValue = hashBuffer;
return hashBuffer;
}
public static UInt32 Compute(byte[] buffer)
{
return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
}
public static UInt32 Compute(UInt32 seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
}
public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
{
return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
}
private static UInt32[] InitializeTable(UInt32 polynomial)
{
if (polynomial == DefaultPolynomial && defaultTable != null)
{
return defaultTable;
}
UInt32[] createTable = new UInt32[256];
for (int i = 0; i < 256; i++)
{
UInt32 entry = (UInt32)i;
for (int j = 0; j < 8; j++)
{
if ((entry & 1) == 1)
entry = (entry >> 1) ^ polynomial;
else
entry = entry >> 1;
}
createTable[i] = entry;
}
if (polynomial == DefaultPolynomial)
{
defaultTable = createTable;
}
return createTable;
}
private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
{
UInt32 crc = seed;
for (int i = start; i < size; i++)
{
unchecked
{
crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
}
}
return crc;
}
private byte[] UInt32ToBigEndianBytes(UInt32 x)
{
return new byte[] { (byte)((x >> 24) & 0xff), (byte)((x >> 16) & 0xff), (byte)((x >> 8) & 0xff), (byte)(x & 0xff) };
}
}//end class: Crc32

Hash MD5 CRC 知识的更多相关文章

  1. Hash(MD5校验工具)

    本站提供md5校验工具下载.Hash(md5校验工具)是一款小巧好用的哈希计算器,Hash支持文件拖放,速度很快,可以计算文件的MD5.SHA1.CRC32 的值.在论坛上.软件发布时经常用Hash ...

  2. 哈希(1) hash的基本知识回顾

    好久没看数据结构了,现在也打不起精神来,翻了一下书,严蔚敏那本书.,以下是书的第9章,发现自己很多时候对知识的认识无法结构化和系统化,都是零散的,模糊的混乱的记忆,以后要有体系, 第9章 查找     ...

  3. Python 文件Hash(MD5,SHA1)

    import hashlib import os,sys   def CalcSha1(filepath):     with open(filepath,'rb') as f:         sh ...

  4. Unity打包同一文件Hash不一样

    问题起因 游戏开发基本都会涉及到资源版本管理及更新,本文记录我在打包过程中遇到的一小问题: 开过中常用于标记资源版本的方法有计算文件Hash.VCS的版本等. 在Unity中对同一个资源文件进行多次打 ...

  5. Golang的md5 hash计算

    Golang计算md5值的方法都是接收byte型slice([]byte).而且使用习惯上也觉得略奇怪. 看了好几个例子才看懂. 感觉Golang标准库在设计这些模块的时候,都会考虑使用带New关键字 ...

  6. 三种Hash算法对比以及秒传原理.

    三种Hash算法对比以及秒传原理 CRC (32/64)   MD5  Sha1 分5个点来说 1.校验值长度 2.校验值类别 3.安全级别 4.应用场景 1).校验值长度 CRC(32/64) 分别 ...

  7. hash算法原理及应用漫谈【加图版】

    原文:https://blog.csdn.net/Tencent_TEG/article/details/103021226 提到hash,相信大多数同学都不会陌生,之前很火现在也依旧很火的技术区块链 ...

  8. 获取文件hash值

    public string getFilesMD5Hash(string file)        {            //MD5 hash provider for computing the ...

  9. Hash校验

    在项目的建设方案中,都会提到数据的安全性,数据的安全性其中又包括数据的完整性和数据保密性,      1.  数据完整性 通过使用Hash校验的方法确保数据的完整性: 传输过程的完整性受到损坏则采取数 ...

随机推荐

  1. 2034-人见人爱A-B(c++实现)

    Problem Description 参加过上个月月赛的同学一定还记得其中的一个最简单的题目,就是{A}+{B},那个题目求的是两个集合的并集,今天我们这个A-B求的是两个集合的差,就是做集合的减法 ...

  2. ZedGraph饼图---傻瓜版

    GraphPane pGraphPane=this.zedGraphControl1.GraphPane;//调用饼图类 pGraphPane.Title.Text = "重金属含量分析图& ...

  3. python中的迭代与递归

    遇到一个情况,需要进行递归操作,但是呢递归次数非常大,有一万多次.先不说一万多次递归,原来的测试代码是java的,没装jdk和编译环境,还是用python吧 先看下原本的java代码: public ...

  4. 8月7号晚7点Autodesk北京办公室,我们来聊聊HTML5/ WebGL 3D 模型浏览技术

    Autodesk 发布了一款完全无需插件的三维模型浏览器 Autodesk 360 Viewer,大家有没有兴趣,下班后过来聊聊吧!   8月7号 周四, 19:00~21:00 Autodesk北京 ...

  5. 在Json解析过程中,我为什么用object1.optInt ,和 object1.optString

    今天在做Json解析的时候,出现了一段代码没执行的问题,于是找了一下原因: 1.原代码是:   发现 红色的一句 没有执行,查看控制台发现了异常 2.修复bug ,正确的代码为        3.总结 ...

  6. 为什么relativelayout.layoutParams的width为-1

    源码里看下就知道了.. -1不代表宽度,代表MATCH_PARENT常量的值public static final int FILL_PARENT = -1; public static final ...

  7. iOS 单例模式 浅叙

    单例模式作用 可以保证在程序运行过程中,一个类只有一个实例,而且该实例易于供外界使用 从而方便地控制了实例个数,并节约系统资源 单例模式使用场合 在整个引用程序中,共享一份资源(这份资源只需要创建初始 ...

  8. 用Reveal分析第三方App的UI

    文章出自:听云博客 Reveal简介: 这是个神奇的工具,它能常透彻地分析个App的UI结构. 这个工具包括两部分,部分是在PC上运行的一个独立应用,即Reveal.app,另一部分代码在你要分析的某 ...

  9. c中的数据类型、常量、变量

    一. 数据 1. 什么是数据 生活中时时刻刻都在跟数据打交道,比如体重数据.血压数据.股价数据等.在我们使用计算机的过程中,会接触到各种各样的数据,有文档数据.图片数据.视频数据,还有聊QQ时产生的文 ...

  10. git 错误:

    git  错误: $ git commit -afatal: Unable to create 'e:/git/Android/XXXXXX/.git/index.lock': File exists ...