• 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;

    }

  • 相关阅读:
    11计划
    Tomcat Server.xml配置详解
    maven常用配置
    [转]Maven的内置属性说明
    PL/SQL Developer使用技巧、快捷键
    01_jeecms建站
    01_bootStrap中Tab页签切换
    利用Java实现文件中的关键字查询
    SVN服务器搭建
    MyEclipse安装插件的几种方法
  • 原文地址:https://www.cnblogs.com/stephen-init/p/4260293.html
Copyright © 2020-2023  润新知