view modules/hash/hash.cpp @ 488:b280d7aca160

Json: add typed valueOr for objects and arrays
author David Demelier <markand@malikania.fr>
date Fri, 13 Nov 2015 19:53:38 +0100
parents 7ee8da32da98
children
line wrap: on
line source

/*
 * hash.cpp -- hash functions
 *
 * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "hash.h"

#include <openssl/sha.h>
#include <openssl/md5.h>

namespace hash {

namespace {

template <typename Context>
using Init	= int (*)(Context *);

template <typename Context>
using Update	= int (*)(Context *, const void *, size_t);

template <typename Context>
using Final	= int (*)(unsigned char *, Context *);

template <typename Context, size_t Length>
std::string convert(const std::string &input, Init<Context> init, Update<Context> update, Final<Context> finalize)
{
	unsigned char digest[Length];
	char hash[Length * 2 + 1];
	
	Context ctx;
	init(&ctx);
	update(&ctx, input.c_str(), input.length());
	finalize(digest, &ctx);
	
	for (unsigned long i = 0; i < Length; i++)
		sprintf(&hash[i * 2], "%02x", (unsigned int)digest[i]);
	
	return std::string(hash);
}

} // !namespace

std::string md5(const std::string &input)
{
	return convert<MD5_CTX, MD5_DIGEST_LENGTH>(input, MD5_Init, MD5_Update, MD5_Final);
}

std::string sha1(const std::string &input)
{
	return convert<SHA_CTX, SHA_DIGEST_LENGTH>(input, SHA1_Init, SHA1_Update, SHA1_Final);
}

std::string sha256(const std::string &input)
{
	return convert<SHA256_CTX, SHA256_DIGEST_LENGTH>(input, SHA256_Init, SHA256_Update, SHA256_Final);
}

std::string sha512(const std::string &input)
{
	return convert<SHA512_CTX, SHA512_DIGEST_LENGTH>(input, SHA512_Init, SHA512_Update, SHA512_Final);
}

} // !hash