//0->0x30(48) 1->0x31(49) 
//将字符串转换为对应16进制数(一般是两位)
string strToHex(string str)
{
    stringstream ss;
    ss << hex << setfill('0');

    for(int i=0;i<str.size();i++){
        // setw(2) 占两位,setfill('0') 空位填充 0
        ss << setw(2) << (int)(unsigned char)str[i];
    }

    return ss.str();
}

image.png

#`hash.digest_size`一旦hash_object对数据进行散列或“消化”,它就是数据的长度或大小(以字节为单位)
print(hex_dig)
>>>a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
print(hash_object.digest_size)
>>>32
print(hash_object.block_size)
>>>64 
print(len(hex_dig))
>>>64
//hash.digest_size=“结果哈希的大小(以字节为单位)。”
//hash.block_size=“哈希算法的内部块大小,以字节为单位。”
//hash.digest_size一旦hash_object对数据进行散列或“消化”,它就是数据的长度或大小

string SHA256Hash(string data)
{
    int len = data.length();
    CryptoPP::byte digest[SHA256::DIGESTSIZE];
    SHA256().CalculateDigest(digest, (CryptoPP::byte*)data.c_str(), len);

    return string((char*)digest, SHA256::DIGESTSIZE);
}
vector<string> calculateHash(string fileName)
{
    //默认情况下,文件以文本模式被打开,这种情况下可能会发生字符转换,例如将回车换行字符(0d0a)转换为新的一行。但是,在二进制模式下不会发生这样的字符转换。因此定义输入文件流时需要加上参数 ios::binary。
    ifstream file(fileName, ios::binary);
    //读取视频文件总长度
    int len;
    //1kb块数
    int blockNum;
    //是对输入文件定位,它有两个参数:第一个参数是偏移量,第二个参数是基地址。
    file.seekg(0, ios::end);
    //函数不需要带参数,它返回当前定位指针的位置,也代表着输入流的大小。
    len = file.tellg();
    //1kb块数 不包含末尾残缺
    blockNum = len / 1024;
    //存放所有hash块
    vector<string> hash(blockNum + 1);

    if(file.is_open()) {
        int lastBlockLen = len - blockNum * 1024;
        
        string block;
        block.resize(lastBlockLen);
        //文件流定位到最后残缺块的起始位置uu
        file.seekg(len - lastBlockLen);
        //读取最后残缺块内容放入block数组开头
        file.read(&block[0], lastBlockLen);
        //获得最后残缺块hash结果
        hash[blockNum] = SHA256Hash(block);
        //前面所有块长度均为1024
        block.resize(1024);
        for(int i = blockNum - 1; i >= 0; i--) {
            int blockStart = i * 1024;
            file.seekg(blockStart);
            file.read(&block[0], 1024);

            hash[i] = SHA256Hash(block + hash[i + 1]);
            
        }
    } else {
        cout << "Can't open the file\n";
        exit(EXIT_FAILURE);
    }

    return hash;
}

test.mp4
image.png
video.mp4
image.png

验证过程:

bool validVideo(vector<pair<string,string>> downvideo,string h0){
    //模拟下载接收视频过程
    string tmph = h0;
    for(int i =0;i<downvideo.size()-1;i++) 
    {
        //每次迭代过程相当于接收一部分视频
        if(tmph != SHA256Hash(downvideo[i].first+downvideo[i+1].second)){

            return false;
        }
        tmph = downvideo[i+1].second;
    }

    return SHA256Hash(downvideo[downvideo.size()-1].first)==downvideo[downvideo.size()-1].second;
}

muddyway
10 声望3 粉丝

« 上一篇
AES cbc ctr

引用和评论

0 条评论