七牛-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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...