ios获取文件MD5值
一般我们在使用http或者socket上传或者下载文件的时候,经常会在完成之后经行一次MD5值得校验(尤其是在断点续传的时候用的更
多),校验MD5值是为了防止在传输的过程当中丢包或者数据包被篡改,在使用MD5之前呢我们应该先了解MD5的一些常识。MD5 百度百科
简单的来说:
1)、MD5是使用哈希算法计算文件或字符串的摘要,对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信 息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列 值。128/ 8 = 16,也就是说MD5得到的是一组16字节长度的八进制。
2)、一般在使用的时候需要将它转换成十六进制输出,并且同时输出为小写。
在有了这些基础知识之后,计算MD5就没有那么大的难度了,最近在做大文件MD5计算的时候在网上搜到了一大堆ios MD5的代码,其中有一大部分都不能用,尤其是 使用
NSFileHandle* handle = [NSFileHandle fileHandleForReadingAtPath:_filePath]; 这种方法的,就最坑了,应为它永远读取的是文件的固定的位置,而并不是计算整个文件的MD5摘要,所以永远让你陷入尴尬的境地。例如:(
NSData* fileData = [handle readDataOfLength: 1024*8]; //永远读取的是从开始位置开始,1024*8长度的文件, 如果使用这种方法的话,必须在每次读取之前将文件读取的位置设置为指定的位置,应该使用NSFileHandle的 - (void)seekToFileOffset:(unsigned long long)offset;
)
下面贴上我找的能用的一段代码:亲测各个平台同一个计算出来的MD5值相同。(在使用的时候,可能会见
FileHashDefaultChunkSizeForReadingData 未定义的情况,那么你应该显示的在头文件里加入混定义:
#define FileHashDefaultChunkSizeForReadingData 1024*8
)
代码如下:
+(NSString*)getFileMD5WithPath:(NSString*)path
{
return (__bridge_transfer NSString *)FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
}
CFStringRef FileMD5HashCreateWithPath(CFStringRef filePath,size_t chunkSizeForReadingData) {
// Declare needed variables
CFStringRef result = NULL;
CFReadStreamRef readStream = NULL;
// Get the file URL
CFURLRef fileURL =
CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
(CFStringRef)filePath,
kCFURLPOSIXPathStyle,
(Boolean)false);
if (!fileURL) goto done;
// Create and open the read stream
readStream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
(CFURLRef)fileURL);
if (!readStream) goto done;
bool didSucceed = (bool)CFReadStreamOpen(readStream);
if (!didSucceed) goto done;
// Initialize the hash object
CC_MD5_CTX hashObject;
CC_MD5_Init(&hashObject);
// Make sure chunkSizeForReadingData is valid
if (!chunkSizeForReadingData) {
chunkSizeForReadingData = FileHashDefaultChunkSizeForReadingData;
}
// Feed the data to the hash object
bool hasMoreData = true;
while (hasMoreData) {
uint8_t buffer[chunkSizeForReadingData];
CFIndex readBytesCount = CFReadStreamRead(readStream,(UInt8 *)buffer,(CFIndex)sizeof(buffer));
if (readBytesCount == -1) break;
if (readBytesCount == 0) {
hasMoreData = false;
continue;
}
CC_MD5_Update(&hashObject,(const void *)buffer,(CC_LONG)readBytesCount);
}
// Check if the read operation succeeded
didSucceed = !hasMoreData;
// Compute the hash digest
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_Final(digest, &hashObject);
// Abort if the read operation failed
if (!didSucceed) goto done;
// Compute the string result
char hash[2 * sizeof(digest) + 1];
for (size_t i = 0; i < sizeof(digest); ++i) {
snprintf(hash + (2 * i), 3, "%02x", (int)(digest[i]));
}
result = CFStringCreateWithCString(kCFAllocatorDefault,(const char *)hash,kCFStringEncodingUTF8);
done:
if (readStream) {
CFReadStreamClose(readStream);
CFRelease(readStream);
}
if (fileURL) {
CFRelease(fileURL);
}
return result;
}
ios获取文件MD5值的更多相关文章
- QT 获取文件MD5值
/* 方法1 */ QFile theFile(fileNamePath); theFile.open(QIODevice::ReadOnly); QByteArray ba = QCryptogra ...
- JAVA中获取文件MD5值的四种方法
JAVA中获取文件MD5值的四种方法其实都很类似,因为核心都是通过JAVA自带的MessageDigest类来实现.获取文件MD5值主要分为三个步骤,第一步获取文件的byte信息,第二步通过Messa ...
- C# 获取文件MD5值的方法
可用于对比文件是否相同 /// <summary> /// 获取文件MD5值 /// </summary> /// <param name="fileName& ...
- 基于js-spark-md5前端js类库,快速获取文件Md5值
js-spark-md5是歪果仁开发的东西,有点多,但是我们只要一个js文件即可,具体类包我存在自己的oschina上,下载地址:https://git.oschina.net/jianqingwan ...
- 获取文件MD5值(JS、JAVA)
文章HTML代码翻译于地址:https://www.cnblogs.com/linyihai/p/7040786.html 文件MD5有啥用? 文 ...
- JAVA中获取文件MD5值的方法
1 DigestUtils.md5Hex(new FileInputStream(path)); 如果你只需要使用标准的MD5,其实一行代码就够了,JAVA自带的commons-codec包就提供了获 ...
- Mac上获取文件md5 值
mac 上获取一个文件的md5值如下 在terminal 上输入下面命令行即可: 方法一: //备注 AccountPassword/check 是全路径 也可以相对路径,我这里是相对路径,用来测试用 ...
- js获取文件MD5值
原文链接:http://www.jianshu.com/p/940a9226fbbd 要在web页面中计算文件的md5值,还好这个项目是只需兼容现代浏览器的,不然要坑死了. 其实对文件进行md5, ...
- 获取文件Md5值
private static string GetFileMD5(string filePath) { string _md5Value = string.Empty; try { if (Syste ...
随机推荐
- [cf1479E]School Clubs
对于当前班级状态$S$,定义一个函数$\varphi(S)$,要求其满足: 令结束状态为$S_{end}$,对于任意$S\ne S_{end}$,若其下一个状态为$S'$,则$E(\varphi(S) ...
- 列生成算法(求解Cutting Stock问题)
列生成是用于求解大规模线性优化问题的一种算法,其实就是单纯形法的一种形式.单纯性可以通过不断迭代,通过换基变量的操作,最终找到问题的最优解.但是当问题的规模很大之后,变量的个数就会增大到在有限时间内无 ...
- 唯一id生成器
public static void main(String[] args) { Jedis jedis = new Jedis("127.0.0.1");//id自增 Long ...
- 洛谷 P6276 - [USACO20OPEN]Exercise P(组合数学+DP)
洛谷题面传送门 废了,又不会做/ll orz czx 写的什么神仙题解,根本看不懂(%%%%%%%%% 首先显然一个排列的贡献为其所有置换环的乘积.考虑如何算之. 碰到很多数的 LCM 之积只有两种可 ...
- JOI 2020 Final 题解
T1. 只不过是长的领带 大水题,把 \(a_i,b_i\) 从小到大排序. 发现最优方案只可能是大的 \(a_i\) 跟大的 \(b_i\) 匹配,小的 \(a_i\) 与小的 \(b_i\) 匹配 ...
- IDE 常用配置
启动进入欢迎页(项目选择页),而非直接进入项目 File > Settings > Appearance & Behavior > System Settings 在Star ...
- C++ and OO Num. Comp. Sci. Eng. - Part 2.
本文参考自<C++ and Object-Oriented Numeric Computing for Scientists and Engineers>. 1. Basic Types ...
- GO 语言使用copy 拷贝切片的问题
使用copy,直接改变原片的值,而不是先创建一个副本.
- Linux—查看内核版本、系统版本、系统位数
一.查看内核版本命令: 1) [root@q1test01 ~]# cat /proc/version Linux version 2.6.9-22.ELsmp (bhcompile@crowe. ...
- (转载)SQL Server 2008 连接JDBC详细图文教程
点评:SQL Server 2008是目前windows上使用最多的sql数据库,2008的安装机制是基于framework重写的,特点是非常耗时间SQL Server 2008是目前windows上 ...