Verified Commit 41751e41 authored by RobLoach's avatar RobLoach
Browse files

sha1: Add love.data.hash(sha1)

parent e62b2a27
......@@ -143,6 +143,9 @@ FLAGS += -I$(CORE_DIR)/vendor/stb
FLAGS += -I$(CORE_DIR)/vendor/libretro-common/include
SOURCES_C += $(CORE_DIR)/vendor/libretro-common/utils/md5.c
# TinySHA1
FLAGS += -I$(CORE_DIR)/vendor/TinySHA1
# ChaiScript
ifeq ($(HAVE_CHAISCRIPT),)
FLAGS += -I$(CORE_DIR)/vendor/chaiscript/include
......
......@@ -18,104 +18,114 @@ std::string data::compress(const std::string& str, int compressionlevel) {
if (compressionlevel < 0 || compressionlevel > 9) {
compressionlevel = Z_BEST_SPEED;
}
z_stream zs;
memset(&zs, 0, sizeof(zs));
z_stream zs;
memset(&zs, 0, sizeof(zs));
if (deflateInit(&zs, compressionlevel) != Z_OK) {
std::cout << "[ChaiLove] [data] deflateInit failed while compressing." << std::endl;
return str;
}
if (deflateInit(&zs, compressionlevel) != Z_OK) {
std::cout << "[ChaiLove] [data] deflateInit failed while compressing." << std::endl;
return str;
}
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size();
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size();
int ret;
char outbuffer[32768];
std::string outstring;
int ret;
char outbuffer[32768];
std::string outstring;
do {
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
do {
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = deflate(&zs, Z_FINISH);
ret = deflate(&zs, Z_FINISH);
if (outstring.size() < zs.total_out) {
outstring.append(outbuffer,
zs.total_out - outstring.size());
}
} while (ret == Z_OK);
if (outstring.size() < zs.total_out) {
outstring.append(outbuffer,
zs.total_out - outstring.size());
}
} while (ret == Z_OK);
deflateEnd(&zs);
deflateEnd(&zs);
if (ret != Z_STREAM_END) {
std::cout << "[ChaiLove] [data] Exception during zlib compression: (" << ret << ") " << zs.msg << std::endl;
return str;
}
if (ret != Z_STREAM_END) {
std::cout << "[ChaiLove] [data] Exception during zlib compression: (" << ret << ") " << zs.msg << std::endl;
return str;
}
return outstring;
return outstring;
}
std::string data::decompress(const std::string& str) {
z_stream zs;
memset(&zs, 0, sizeof(zs));
z_stream zs;
memset(&zs, 0, sizeof(zs));
if (inflateInit(&zs) != Z_OK)
throw(std::runtime_error("inflateInit failed while decompressing."));
if (inflateInit(&zs) != Z_OK)
throw(std::runtime_error("inflateInit failed while decompressing."));
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size();
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size();
int ret;
char outbuffer[32768];
std::string outstring;
int ret;
char outbuffer[32768];
std::string outstring;
do {
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
do {
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = inflate(&zs, 0);
ret = inflate(&zs, 0);
if (outstring.size() < zs.total_out) {
outstring.append(outbuffer,
zs.total_out - outstring.size());
}
} while (ret == Z_OK);
if (outstring.size() < zs.total_out) {
outstring.append(outbuffer,
zs.total_out - outstring.size());
}
} while (ret == Z_OK);
inflateEnd(&zs);
inflateEnd(&zs);
if (ret != Z_STREAM_END) {
std::ostringstream oss;
oss << "[ChaiLove] [data] Exception during zlib decompression: (" << ret << ") " << zs.msg;
throw(std::runtime_error(oss.str()));
}
if (ret != Z_STREAM_END) {
std::ostringstream oss;
oss << "[ChaiLove] [data] Exception during zlib decompression: (" << ret << ") " << zs.msg;
throw(std::runtime_error(oss.str()));
}
return outstring;
return outstring;
}
std::string data::hash(const std::string& hashFunction, const std::string& data) {
if (hashFunction == "md5") {
const char* input = data.c_str();
unsigned char digest[16];
// Calculate the MD5 hash using libretro-common.
MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, input, strlen(input));
MD5_Final(digest, &context);
// Construct the MD5 hash string.
char md5string[33];
for (int i = 0; i < 16; ++i) {
snprintf(&md5string[i * 2], sizeof(&md5string[i * 2]), "%02x", (unsigned int)digest[i]);
}
// Output the hash.
std::string output(md5string);
return output;
}
std::cout << "[ChaiLove] Error: Hash function not found: " << hashFunction << "." << std::endl;
return "";
if (hashFunction == "md5") {
const char* input = data.c_str();
unsigned char digest[16];
// Calculate the MD5 hash using libretro-common.
MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, input, strlen(input));
MD5_Final(digest, &context);
// Construct the MD5 hash string.
char md5string[33];
for (int i = 0; i < 16; ++i) {
snprintf(&md5string[i * 2], sizeof(&md5string[i * 2]), "%02x", (unsigned int)digest[i]);
}
// Output the hash.
std::string output(md5string);
return output;
}
if (hashFunction == "sha1") {
sha1::SHA1 s;
s.processBytes(data.c_str(), data.size());
uint32_t digest[5];
s.getDigest(digest);
char tmp[48];
snprintf(tmp, 45, "%08x %08x %08x %08x %08x", digest[0], digest[1], digest[2], digest[3], digest[4]);
return std::string(tmp);
}
std::cout << "[ChaiLove] Error: Hash function not found: " << hashFunction << "." << std::endl;
return "";
}
} // namespace love
......@@ -36,10 +36,10 @@ class data {
/**
* Compute the message digest of specified string with specified algorithm.
*
* @param hashFunction Hash algorithm to use (md5).
* @param hashFunction Hash algorithm to use (md5, sha1).
* @param data String to hash.
*
* @todo Add sha1, sha256, sha512, etc.
* @todo Add sha256, sha512, etc.
*
* @return Raw message digest string.
*/
......
......@@ -7,3 +7,6 @@ assert_equal(decompressed, text, "love.data.decompress()")
var md5Hash = love.data.hash("md5", "Hello World")
assert_equal(md5Hash, "b10a8db164e0754105b7a99be72e3fe5", "love.data.hash('md5')")
var sha1Hash = love.data.hash("sha1", "Hello World")
assert_equal(sha1Hash, "0a4d55a8d778e5022fab701977c5d840bbc486d0", "love.data.hash('sha1')")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment