七牛-ETag演算法(OC)

来源:https://www.cnblogs.com/lybSkill/archive/2020/03/02/11992312.html
-Advertisement-
Play Games

一、摘要 1.七牛上傳文件,用hash來唯一標識七牛存儲空間中的某個文件,該hash是以ETag演算法計算出的一段哈希值; 2.演算法介紹:https://developer.qiniu.com/kodo/manual/1231/appendix; 3.七牛的提供的實現語言中(https://githu ...


一、摘要

1.七牛上傳文件,用hash來唯一標識七牛存儲空間中的某個文件,該hash是以ETag演算法計算出的一段哈希值;

2.演算法介紹:https://developer.qiniu.com/kodo/manual/1231/appendix

3.七牛的提供的實現語言中(https://github.com/qiniu/qetag),沒有給出OC實現;

4.參考js代碼:https://www.jianshu.com/p/3785fc314fc5

二、代碼

- (void)test2 {
    /*測試鏈接
     http://yqq.file.mediportal.com.cn/yqq_5b911b43955f06317c6bd792/3974e8eaab11b2dd5b357e60e5a587d1  etag:FtfVrVsdpVf9t_tCfyvsVC-1p6aW
     4M以上文件親測正確
     */
    
    NSURL *url = [NSURL URLWithString:@"http://yqq.file.mediportal.com.cn/yqq_5b911b43955f06317c6bd792/3974e8eaab11b2dd5b357e60e5a587d1"];
    NSError *error;
    NSData * data = [NSData dataWithContentsOfURL:url options:NSDataReadingMapped error:&error];
    NSString *etag = [self caculateETagWith:data];
    NSLog(@"etag------%@", etag);
}

//演算法實現
- (NSString *)caculateETagWith:(NSData *)data
{
    unsigned long blockSize = 4 * 1024 * 1024;
    NSMutableData *sha1Data = [NSMutableData data];
    Byte prefix = 0x16;
    int blockCount = 0;
    
    unsigned long bufferSize = [data length];
    //獲取餘數
    unsigned long remainder = bufferSize % blockSize;
    //獲取商
    double fa = (double)bufferSize / blockSize;
    //向下取整
    blockCount = floor(fa);
    
    if (bufferSize > blockSize) {//大於4M的文件
        NSMutableData *sha2Data = [NSMutableData data];
        for (int i = 0; i < blockCount+1; i++) {
            NSUInteger length = blockSize;
            if (i == blockCount && remainder > 0) {
                length = remainder;
            }
            //將每個塊(包括4M塊和小於4M的塊)進行sha1加密並拼接起來
            NSData *subData = [data subdataWithRange:NSMakeRange(i * blockSize, length)];
            [sha2Data appendData:[self sha1:subData]];
        }
        //將拼接塊進行二次sha1加密
        [sha1Data appendData:[self sha1:sha2Data]];
    } else {
        [sha1Data appendData:[self sha1:data]];
    }

    if (!sha1Data.length) return @"Fto5o-5ea0sNMlW_75VgGJCv2AcJ";
    
    NSData *sha1Buffer = sha1Data;
    if (bufferSize > blockSize) {
        //大於4M,頭部拼接0x96單個位元組
        prefix = 0x96;
    }
    
    Byte preByte[] = {prefix};
    NSMutableData *mutaData = [NSMutableData dataWithBytes:preByte length:1];
    [mutaData appendData:sha1Buffer];
    
    //將長度為21個位元組的二進位數據進行url_safe_base64計算
    return [self safeBase64WithSha1Str:mutaData];
}

/*
 sha1加密(加密後的data長度為20)
 */
- (NSData*)sha1:(NSData *)data
{
    //註:如果用以下代碼,轉換出的data長度為40
//    const char *cstr = [sourceStr cStringUsingEncoding:NSUTF8StringEncoding];
//    NSData *data = [NSData dataWithBytes:cstr length:sourceStr.length];
//    NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
//    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
//        [output appendFormat:@"%02x", digest[i]];
//    return output;
    
    //sha1Data長度為20(CC_SHA1_DIGEST_LENGTH系統設定為20)
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
    NSData * sha1Data = [[NSData alloc] initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
    return sha1Data;
}

- (NSString *)safeBase64WithSha1Str:(NSData *)base64
{
    //Base64編碼中包含有"+,/,="不安全的URL字元串,我們要對這些字元進行轉換
    NSString *base64Str = [GTMBase64 encodeBase64Data:base64];

    NSMutableString *safeBase64Str = [[NSMutableString alloc] initWithString:base64Str];

    safeBase64Str = (NSMutableString *)[safeBase64Str stringByReplacingOccurrencesOfString:@"+"withString:@"-"];

    safeBase64Str = (NSMutableString *)[safeBase64Str stringByReplacingOccurrencesOfString:@"/"withString:@"_"];

    safeBase64Str = (NSMutableString *)[safeBase64Str stringByReplacingOccurrencesOfString:@"="withString:@""];
    
    return safeBase64Str;
}

說明:url?stat可查看七牛文件的etag值(即hash值),如下:

http://yqq.file.mediportal.com.cn/yqq_5b911b43955f06317c6bd792/3974e8eaab11b2dd5b357e60e5a587d1?stat

     {"fsize":687810,"uploaded":687810,"hash":"FtfVrVsdpVf9t_tCfyvsVC-1p6aW","mimeType":"image/jpeg"}

 

 

GitHub

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文源碼: "GitHub·點這裡" || "GitEE·點這裡" 一、MySQL邏輯架構 1、邏輯架構圖 基於下麵的邏輯架構圖,可以大致熟悉MySQL各個架構組件之間的協同工作關係。 很經典的C/S架構風格,即客戶端/服務端模式。 2、分層描述 客戶端連接 通常會進行連接池管理,連接用戶許可權認證, ...
  • "概要" "Spark 單機環境配置" "JDK 環境配置" "Spark 環境配置" "python 環境配置" "Spark 使用示例" "示例代碼 (order\_stat.py)" "測試用的 csv 文件內容 (orders.csv)" "運行結果" 概要 大數據和人工智慧已經宣傳了好多年 ...
  • 查詢中出現兩個表的連接,下麵通過實例來講解一下各種連接查詢的不同之處 表 a,和表b 如下圖 a 表中 有 abcd b表中有 abcf 內連接: 得出結果 如圖,選擇等值的結果(abc) 左連接: 查詢結果如圖,選擇a表為基準。(abcd) 右連接: 查詢結果如圖,選擇a表為基準。(abcf) 全 ...
  • 第一步 下載安裝包: 官網 畢竟是甲骨文公司的產品,去官網下真的慢! 這裡有兩個供選擇的,我建議選第一個(因為我先下了第二個,結果失敗了,不知道為什麼總是出錯。) 下載完自行選擇路徑解壓就可以了。 第二步 配置my.ini: 在根目錄下新建文本文件,將下麵的複製上,註意修改尾碼為.ini [mysq ...
  • 疫情已經持續了好幾個月了,作為程式員滴我們也幫不上什麼忙,只有老老實實呆在家裡或者出門一定戴口罩準守一些規則,不給國家添亂。不過最近疫情開始有所扭轉,但是還是對國家經濟,對企業業務造成了很大的影響,我也被停止了實習。接下來,可能會面臨著失業,破產等等嚴肅的問題。但是我們還是需要繼續學習,提高自己的競 ...
  • Oracle體繫結構 實例: 一個操作系統只有一個 Oracle 資料庫 一個 Oracle 資料庫可以有多個 Oracle 實例(通常只安裝一個實例) 一個實例對應著一系列的後臺進程和記憶體結構 表空間: 一個實例在邏輯上可以分成若幹個表空間 表空間是 Oracle 對數據文件的邏輯映射 表空間不屬 ...
  • Socket通信有兩種主要方式:TCP協議和UDP協議,兩者區別是TCP協議要首先和接收方要建立連接然後發送數據,這樣數據能保證送達,但速度較慢;UDP協議首先把數據打包,然後直接發送到接收方,無需建立連接誒,速度快,但容易丟失數據。這裡是一個簡單的基於TCP協議的通信實例: 直接上代碼: 首先是j ...
  • 去年計劃完成移動互聯網技術開發三部曲:微信小程式開發、iOS App開發和Android App開發的。故系列文章命名為:一個人開發一個App……開頭。 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...