1#ifndef ROSE_Combinatorics_H
2#define ROSE_Combinatorics_H
4#include <rosePublicConfig.h>
6#include <Rose/Constants.h>
7#include <ROSE_UNUSED.h>
15#include <Rose/Exception.h>
16#include <Sawyer/Assert.h>
17#include <Sawyer/Synchronization.h>
23#ifdef ROSE_HAVE_LIBGCRYPT
30namespace Combinatorics {
39 T next = retval * n--;
56permute(std::vector<T> &values, uint64_t pn,
size_t sz =
UNLIMITED)
60 assert(sz<=values.size());
61 assert(pn<factorial(sz));
62 for (
size_t i=0; i<sz; ++i) {
63 uint64_t radix = sz - i;
64 uint64_t idx = pn % radix;
65 std::swap(values[i+idx], values[i]);
79 nitems = std::min(nitems, vector.size());
80 limit = std::min(limit, nitems);
82 for (
size_t i=0; i<limit; ++i) {
84 std::swap(vector[i], vector[j]);
115reorder(std::vector<T> &values,
const std::vector<size_t> &remap) {
116 assert(values.size() == remap.size());
119 std::vector<T> old = values;
120 for (
size_t i = 0; i < old.size(); ++i)
121 values[i] = old[remap[i]];
209 void insert(
const std::string &x) { append((
const uint8_t*)x.c_str(), x.size()); }
210 void insert(uint64_t x) { append((uint8_t*)&x,
sizeof x); }
211 void insert(
const uint8_t *x,
size_t size) { append(x, size); }
212 void insert(
const std::vector<uint8_t> &v) { append(v.data(), v.size()); }
215 while (stream.good()) {
216 stream.read(buf,
sizeof buf);
217 append((
const uint8_t*)buf, stream.gcount());
228 virtual void append(
const uint8_t *message,
size_t messageSize) = 0;
265 virtual std::shared_ptr<Hasher> create()
const = 0;
298 HasherFactory::Instance().registerMaker(hashType,
this);
305 virtual std::shared_ptr<Hasher>
create()
const
307 return std::make_shared<T>();
341 std::shared_ptr<Hasher>
createHasher(
const std::string& hashType)
const;
352 std::map<std::string, IHasherMaker* > hashMakers;
361template<
int hashAlgorithmId>
363#ifdef ROSE_HAVE_LIBGCRYPT
369 #ifdef ROSE_HAVE_LIBGCRYPT
370 if (gcry_md_open(&md_, hashAlgorithmId, 0) != GPG_ERR_NO_ERROR)
371 throw Exception(
"cannot initialize libgcrypt hash " + std::string(gcry_md_algo_name(hashAlgorithmId)));
373 throw Exception(
"ROSE was not configured with libgcrypt");
378 #ifdef ROSE_HAVE_LIBGCRYPT
379 if (gcry_md_copy(&md_, other.md_) != GPG_ERR_NO_ERROR)
380 throw Exception(
"cannot copy libgcrypt hash " + std::string(gcry_md_algo_name(hashAlgorithmId)));
383 throw Exception(
"ROSE was not configured with libgcrypt");
388 #ifdef ROSE_HAVE_LIBGCRYPT
394 #ifdef ROSE_HAVE_LIBGCRYPT
396 if (gcry_md_copy(&md_, other.md_) != GPG_ERR_NO_ERROR)
397 throw Exception(
"cannot copy libgcrypt hash " + std::string(gcry_md_algo_name(hashAlgorithmId)));
400 throw Exception(
"ROSE was not configured with libgcrypt");
405 #ifdef ROSE_HAVE_LIBGCRYPT
412 if (digest_.empty()) {
413 #ifdef ROSE_HAVE_LIBGCRYPT
415 digest_.resize(gcry_md_get_algo_dlen(hashAlgorithmId), 0);
416 uint8_t *d = gcry_md_read(md_, hashAlgorithmId);
418 memcpy(&digest_[0], d, digest_.size());
420 ASSERT_not_reachable(
"ROSE was not configured with libgcrypt");
426 void append(
const uint8_t *message,
size_t messageSize) {
427 ASSERT_require(message || 0==messageSize);
428 #ifdef ROSE_HAVE_LIBGCRYPT
429 if (!digest_.empty())
430 throw Exception(
"cannot append after returning digest");
432 gcry_md_write(md_, message, messageSize);
434 ASSERT_not_reachable(
"ROSE was not configured with libgcrypt");
439#ifdef ROSE_HAVE_LIBGCRYPT
440typedef HasherGcrypt<GCRY_MD_MD5>
HasherMd5;
461 HasherFnv(): partial_(0xcbf29ce484222325ull) {}
463 void append(
const uint8_t *message,
size_t messageSize)
override;
464 uint64_t partial()
const {
return partial_; }
471 static const uint32_t roundConstants_[64];
473 size_t processedBytes_;
474 std::vector<uint8_t> leftoverBytes_;
479 void append(
const uint8_t *message,
size_t messageSize)
override;
481 uint8_t messageByte(
size_t index,
const uint8_t *message,
size_t messageSize);
482 bool getNextChunk(
const uint8_t* &message ,
size_t &messageSize , uint32_t words[16] );
483 void accumulateChunk(
const uint32_t chunk[16]);
489template<
class T,
class U>
490std::vector<std::pair<T, U> >
491zip(
const std::vector<T> &first,
const std::vector<U> &second) {
492 size_t retvalSize = std::min(first.size(), second.size());
493 std::vector<std::pair<T, U> > retval;
494 retval.reserve(retvalSize);
495 for (
size_t i = 0; i < retvalSize; ++i)
496 retval.push_back(std::pair<T, U>(first[i], second[i]));
501template<
class T,
class U>
502std::pair<std::vector<T>, std::vector<U> >
503unzip(
const std::vector<std::pair<T, U> > &pairs) {
504 std::pair<std::vector<T>, std::vector<U> > retval;
505 retval.first.reserve(pairs.size());
506 retval.second.reserve(pairs.size());
507 for (
size_t i = 0; i < pairs.size(); ++i) {
508 retval.first.push_back(pairs[i].first);
509 retval.second.push_back(pairs[i].second);
Fowler-Noll-Vo hashing using the Hasher interface.
void append(const uint8_t *message, size_t messageSize) override
Insert data into the digest.
const Digest & digest() override
Return the digest.
Hasher for any libgcrypt hash algorithm.
void append(const uint8_t *message, size_t messageSize)
Insert data into the digest.
void clear()
Reset the hasher to its initial state.
const Digest & digest()
Return the digest.
void append(const uint8_t *message, size_t messageSize) override
Insert data into the digest.
void clear() override
Reset the hasher to its initial state.
const Digest & digest() override
Return the digest.
Exception(const std::string &mesg)
Constructor.
HasherFactory is a singleton that creates and returns Hashers by name.
void registerMaker(const std::string &hashType, IHasherMaker *createHasherPtr)
Adds a new @HasherMaker to the HasherFactory.
static HasherFactory & Instance()
Returns a reference to the HasherFactory singleton.
std::shared_ptr< Hasher > createHasher(const std::string &hashType) const
Creates a registered Hasher by type from the map.
Templated to create any Hasher and register it with HasherFactory.
HasherMaker(const std::string &hashType)
Creates a HasherMaker and registers it with HasherFactory.
virtual std::shared_ptr< Hasher > create() const
Creates a Hasher (the type of Hasher is determined by the template T) and returns it as a shared_ptr.
Common subclass all the classes that construct Hashers (for the HasherFactory)
void insert(const std::string &x)
Insert data into the digest.
void insert(uint64_t x)
Insert data into the digest.
uint64_t make64Bits(const Digest &)
Returns the hash as a 64 bit int.
std::string toString()
String representation of the digest.
std::vector< uint8_t > Digest
The digest of the input message.
void insert(const std::vector< uint8_t > &v)
Insert data into the digest.
static std::string toString(const Digest &)
Convert a digest to a hexadecimal string.
virtual void clear()
Reset the hasher to its initial state.
virtual const Digest & digest()
Return the digest.
void print(std::ostream &)
Print a hash to a stream.
uint64_t make64Bits()
Returns the hash as a 64 bit int.
void insert(std::istream &stream)
Insert data into the digest.
void insert(const uint8_t *x, size_t size)
Insert data into the digest.
virtual void append(const uint8_t *message, size_t messageSize)=0
Insert data into the digest.
Base class for all ROSE exceptions.
ROSE_DLL_API bool flip_coin()
Simulate flipping a coin.
HasherGcrypt< 0 > HasherSha1
SHA1 hasher.
std::vector< std::pair< T, U > > zip(const std::vector< T > &first, const std::vector< U > &second)
Convert two vectors to a vector of pairs.
HasherGcrypt< 0 > HasherSha384
SHA-384 hasher.
HasherGcrypt< 0 > HasherCrc32
ISO 3309 hasher.
void reorder(std::vector< T > &values, const std::vector< size_t > &remap)
Reorder the values of one vector according to another.
ROSE_DLL_API std::string toBase62String(uint64_t num)
Converts a 64 bit in to base 62 (All letters and numbers).
HasherGcrypt< 0 > HasherMd5
MD5 hasher.
void shuffle(std::vector< T > &vector, size_t nitems=UNLIMITED, size_t limit=UNLIMITED)
Shuffle the values of a vector.
std::pair< std::vector< T >, std::vector< U > > unzip(const std::vector< std::pair< T, U > > &pairs)
Convert a vector of pairs to a pair of vectors.
ROSE_DLL_API uint64_t fromBase62String(const std::string &base62)
Converts a base-62 (All letters and numbers) number to a 64 bit int.
HasherGcrypt< 0 > HasherSha256
SHA-256 hasher.
HasherGcrypt< 0 > HasherSha512
SHA-512 hasher.
const size_t UNLIMITED
Effectively unlimited size.
size_t fastRandomIndex(size_t n, size_t seed=0)
Thread-safe random number generator.