create sha1_info
This commit is contained in:
parent
e251a3ce51
commit
1dee83b01f
@ -13,6 +13,9 @@ add_executable(tox_ngc_ft1_tool
|
|||||||
./tox_utils.hpp
|
./tox_utils.hpp
|
||||||
./tox_utils.cpp
|
./tox_utils.cpp
|
||||||
|
|
||||||
|
./hash_utils.hpp
|
||||||
|
./hash_utils.cpp
|
||||||
|
|
||||||
./tox_callbacks.hpp
|
./tox_callbacks.hpp
|
||||||
./tox_callbacks.cpp
|
./tox_callbacks.cpp
|
||||||
|
|
||||||
@ -21,8 +24,8 @@ add_executable(tox_ngc_ft1_tool
|
|||||||
|
|
||||||
./state.hpp
|
./state.hpp
|
||||||
|
|
||||||
./send_states/sha1_start.hpp
|
./states/state_send_start_sha1.hpp
|
||||||
./send_states/sha1_start.cpp
|
./states/state_send_start_sha1.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_features(tox_ngc_ft1_tool PUBLIC cxx_std_17)
|
target_compile_features(tox_ngc_ft1_tool PUBLIC cxx_std_17)
|
||||||
@ -31,5 +34,8 @@ target_link_libraries(tox_ngc_ft1_tool
|
|||||||
toxcore
|
toxcore
|
||||||
tox_ngc_ext
|
tox_ngc_ext
|
||||||
tox_ngc_ft1
|
tox_ngc_ft1
|
||||||
|
|
||||||
|
mio::mio
|
||||||
|
sha1::sha1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
64
src/ft_sha1_info.hpp
Normal file
64
src/ft_sha1_info.hpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct SHA1Digest {
|
||||||
|
std::array<uint8_t, 20> data;
|
||||||
|
|
||||||
|
SHA1Digest(const std::vector<uint8_t>& v) {
|
||||||
|
assert(v.size() == data.size());
|
||||||
|
for (size_t i = 0; i < data.size(); i++) {
|
||||||
|
data[i] = v[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FTInfoSHA1 {
|
||||||
|
std::string file_name;
|
||||||
|
uint64_t file_size {0};
|
||||||
|
static constexpr size_t chunk_size {4*1024}; // 4KiB for now
|
||||||
|
std::vector<SHA1Digest> chunks;
|
||||||
|
|
||||||
|
std::vector<uint8_t> toBuffer(void) const {
|
||||||
|
std::vector<uint8_t> buffer;
|
||||||
|
|
||||||
|
assert(!file_name.empty());
|
||||||
|
// TODO: optimize
|
||||||
|
for (size_t i = 0; i < 256; i++) {
|
||||||
|
if (i < file_name.size()) {
|
||||||
|
buffer.push_back(file_name.at(i));
|
||||||
|
} else {
|
||||||
|
buffer.push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(buffer.size() == 256);
|
||||||
|
|
||||||
|
{ // HACK: endianess
|
||||||
|
buffer.push_back((file_size>>(0*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(1*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(2*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(3*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(4*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(5*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(6*8)) & 0xff);
|
||||||
|
buffer.push_back((file_size>>(7*8)) & 0xff);
|
||||||
|
}
|
||||||
|
assert(buffer.size() == 256+8);
|
||||||
|
|
||||||
|
// chunk size?
|
||||||
|
|
||||||
|
for (const auto& chunk : chunks) {
|
||||||
|
for (size_t i = 0; i < chunk.data.size(); i++) {
|
||||||
|
buffer.push_back(chunk.data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(buffer.size() == 256+8+20*chunks.size());
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
26
src/hash_utils.cpp
Normal file
26
src/hash_utils.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "./hash_utils.hpp"
|
||||||
|
|
||||||
|
#include <sha1.h>
|
||||||
|
|
||||||
|
// returns the 20bytes sha1 hash
|
||||||
|
std::vector<uint8_t> hash_sha1(const uint8_t* data, size_t size) {
|
||||||
|
SHA1_CTX ctx;
|
||||||
|
SHA1Init(&ctx);
|
||||||
|
|
||||||
|
{ // lib only takes uint32_t sizes, so chunk it
|
||||||
|
constexpr size_t hash_block_size {0xffffffff};
|
||||||
|
size_t i = 0;
|
||||||
|
for (; i + hash_block_size < size; i += hash_block_size) {
|
||||||
|
SHA1Update(&ctx, reinterpret_cast<const uint8_t*>(data) + i, hash_block_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < size) {
|
||||||
|
SHA1Update(&ctx, reinterpret_cast<const uint8_t*>(data) + i, size - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> sha1_hash(20);
|
||||||
|
SHA1Final(sha1_hash.data(), &ctx);
|
||||||
|
return sha1_hash;
|
||||||
|
}
|
||||||
|
|
10
src/hash_utils.hpp
Normal file
10
src/hash_utils.hpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// returns the 20bytes sha1 hash
|
||||||
|
std::vector<uint8_t> hash_sha1(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
|
inline std::vector<uint8_t> hash_sha1(const char* data, size_t size) { return hash_sha1(reinterpret_cast<const uint8_t*>(data), size); }
|
||||||
|
|
@ -1,48 +0,0 @@
|
|||||||
#include "./sha1_start.hpp"
|
|
||||||
|
|
||||||
#include "../tox_client.hpp"
|
|
||||||
|
|
||||||
namespace SendStates {
|
|
||||||
|
|
||||||
SHA1Start::SHA1Start(ToxClient& tcl, const CommandLine& cl) : StateI(tcl) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHA1Start::iterate(void) {
|
|
||||||
_tcl._tox;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<StateI> SHA1Start::nextState(void) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sha1_info
|
|
||||||
void SHA1Start::onFT1ReceiveRequestSHA1Info(uint32_t, uint32_t, const uint8_t*, size_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHA1Start::onFT1ReceiveInitSHA1Info(uint32_t, uint32_t, const uint8_t*, size_t, const uint8_t, const size_t) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHA1Start::onFT1ReceiveDataSHA1Info(uint32_t, uint32_t, uint8_t, size_t, const uint8_t*, size_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHA1Start::onFT1SendDataSHA1Info(uint32_t, uint32_t, uint8_t, size_t, uint8_t*, size_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// sha1_chunk
|
|
||||||
void SHA1Start::onFT1ReceiveRequestSHA1Chunk(uint32_t, uint32_t, const uint8_t*, size_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHA1Start::onFT1ReceiveInitSHA1Chunk(uint32_t, uint32_t, const uint8_t*, size_t, const uint8_t, const size_t) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHA1Start::onFT1ReceiveDataSHA1Chunk(uint32_t, uint32_t, uint8_t, size_t, const uint8_t*, size_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHA1Start::onFT1SendDataSHA1Chunk(uint32_t, uint32_t, uint8_t, size_t, uint8_t*, size_t) {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // SendStates
|
|
||||||
|
|
93
src/states/state_send_start_sha1.cpp
Normal file
93
src/states/state_send_start_sha1.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "./state_send_start_sha1.hpp"
|
||||||
|
|
||||||
|
#include "../tox_client.hpp"
|
||||||
|
#include "../tox_utils.hpp"
|
||||||
|
#include "../hash_utils.hpp"
|
||||||
|
#include "../ft_sha1_info.hpp"
|
||||||
|
|
||||||
|
#include <mio/mio.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace States {
|
||||||
|
|
||||||
|
SendStartSHA1::SendStartSHA1(ToxClient& tcl, const CommandLine& cl) : StateI(tcl) {
|
||||||
|
std::cout << "SendStartSHA1 start building sha1_info\n";
|
||||||
|
std::error_code err;
|
||||||
|
_file_map = mio::make_mmap_source(cl.send_path, 0, mio::map_entire_file, err);
|
||||||
|
|
||||||
|
// TODO: propper error checking
|
||||||
|
|
||||||
|
assert(!_file_map.empty());
|
||||||
|
|
||||||
|
// build info
|
||||||
|
_sha1_info.file_name = "testfile.bin";
|
||||||
|
_sha1_info.file_size = _file_map.length();
|
||||||
|
|
||||||
|
{ // build chunks
|
||||||
|
size_t i = 0;
|
||||||
|
for (; i + FTInfoSHA1::chunk_size < _file_map.length(); i += FTInfoSHA1::chunk_size) {
|
||||||
|
_sha1_info.chunks.push_back(hash_sha1(_file_map.data()+i, FTInfoSHA1::chunk_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < _file_map.length()) {
|
||||||
|
_sha1_info.chunks.push_back(hash_sha1(_file_map.data()+i, _file_map.length()-i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // unload file and remap (for when the file was large)
|
||||||
|
_file_map.unmap();
|
||||||
|
_file_map = mio::make_mmap_source(cl.send_path, 0, mio::map_entire_file, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "SHA1Start chunks: " << _sha1_info.chunks.size() << "\n";
|
||||||
|
|
||||||
|
_sha1_info_data = _sha1_info.toBuffer();
|
||||||
|
|
||||||
|
std::cout << "SHA1Start sha1_info size: " << _sha1_info_data.size() << "\n";
|
||||||
|
|
||||||
|
_sha1_info_hash = hash_sha1(_sha1_info_data.data(), _sha1_info_data.size());
|
||||||
|
|
||||||
|
std::cout << "SHA1Start sha1_info_hash: " << bin2hex(_sha1_info_hash) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendStartSHA1::iterate(void) {
|
||||||
|
(void)_tcl._tox;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<StateI> SendStartSHA1::nextState(void) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sha1_info
|
||||||
|
void SendStartSHA1::onFT1ReceiveRequestSHA1Info(uint32_t, uint32_t, const uint8_t*, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendStartSHA1::onFT1ReceiveInitSHA1Info(uint32_t, uint32_t, const uint8_t*, size_t, const uint8_t, const size_t) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendStartSHA1::onFT1ReceiveDataSHA1Info(uint32_t, uint32_t, uint8_t, size_t, const uint8_t*, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendStartSHA1::onFT1SendDataSHA1Info(uint32_t, uint32_t, uint8_t, size_t, uint8_t*, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// sha1_chunk
|
||||||
|
void SendStartSHA1::onFT1ReceiveRequestSHA1Chunk(uint32_t, uint32_t, const uint8_t*, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendStartSHA1::onFT1ReceiveInitSHA1Chunk(uint32_t, uint32_t, const uint8_t*, size_t, const uint8_t, const size_t) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendStartSHA1::onFT1ReceiveDataSHA1Chunk(uint32_t, uint32_t, uint8_t, size_t, const uint8_t*, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendStartSHA1::onFT1SendDataSHA1Chunk(uint32_t, uint32_t, uint8_t, size_t, uint8_t*, size_t) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // States
|
||||||
|
|
@ -3,15 +3,18 @@
|
|||||||
#include "../state.hpp"
|
#include "../state.hpp"
|
||||||
|
|
||||||
#include "../command_line.hpp"
|
#include "../command_line.hpp"
|
||||||
|
#include "../ft_sha1_info.hpp"
|
||||||
|
|
||||||
namespace SendStates {
|
#include <mio/mio.hpp>
|
||||||
|
|
||||||
|
namespace States {
|
||||||
|
|
||||||
// we are hashing the given file
|
// we are hashing the given file
|
||||||
// does not react to any ft events
|
// does not react to any ft events
|
||||||
struct SHA1Start final : public StateI {
|
struct SendStartSHA1 final : public StateI {
|
||||||
public: // general interface
|
public: // general interface
|
||||||
SHA1Start(ToxClient& tcl, const CommandLine& cl);
|
SendStartSHA1(ToxClient& tcl, const CommandLine& cl);
|
||||||
~SHA1Start(void) override = default;
|
~SendStartSHA1(void) override = default;
|
||||||
|
|
||||||
bool iterate(void) override;
|
bool iterate(void) override;
|
||||||
std::unique_ptr<StateI> nextState(void) override;
|
std::unique_ptr<StateI> nextState(void) override;
|
||||||
@ -28,7 +31,13 @@ struct SHA1Start final : public StateI {
|
|||||||
bool onFT1ReceiveInitSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size) override;
|
bool onFT1ReceiveInitSHA1Chunk(uint32_t group_number, uint32_t peer_number, const uint8_t* file_id, size_t file_id_size, const uint8_t transfer_id, const size_t file_size) override;
|
||||||
void onFT1ReceiveDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size) override;
|
void onFT1ReceiveDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, const uint8_t* data, size_t data_size) override;
|
||||||
void onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) override;
|
void onFT1SendDataSHA1Chunk(uint32_t group_number, uint32_t peer_number, uint8_t transfer_id, size_t data_offset, uint8_t* data, size_t data_size) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mio::mmap_source _file_map;
|
||||||
|
FTInfoSHA1 _sha1_info;
|
||||||
|
std::vector<uint8_t> _sha1_info_data;
|
||||||
|
std::vector<uint8_t> _sha1_info_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // SendStates
|
} // States
|
||||||
|
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#include "./tox_utils.hpp"
|
#include "./tox_utils.hpp"
|
||||||
#include "./tox_callbacks.hpp"
|
#include "./tox_callbacks.hpp"
|
||||||
#include "send_states/sha1_start.hpp"
|
|
||||||
|
#include "./states/state_send_start_sha1.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
@ -124,7 +125,7 @@ ToxClient::ToxClient(const CommandLine& cl) :
|
|||||||
{ // state factory // TODO: extract
|
{ // state factory // TODO: extract
|
||||||
// sender
|
// sender
|
||||||
if (!cl.send_path.empty()) {
|
if (!cl.send_path.empty()) {
|
||||||
_state = std::make_unique<SendStates::SHA1Start>(*this, cl);
|
_state = std::make_unique<States::SendStartSHA1>(*this, cl);
|
||||||
} else { // receiver
|
} else { // receiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
// fwd
|
// fwd
|
||||||
namespace SendStates {
|
namespace States {
|
||||||
struct SHA1Start;
|
struct SendStartSHA1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ToxClient {
|
struct ToxClient {
|
||||||
@ -71,6 +71,6 @@ struct ToxClient {
|
|||||||
std::unique_ptr<StateI> _state;
|
std::unique_ptr<StateI> _state;
|
||||||
|
|
||||||
// TODO: this is a hack, make better?
|
// TODO: this is a hack, make better?
|
||||||
friend SendStates::SHA1Start;
|
friend States::SendStartSHA1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user