mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-13 01:07:24 -05:00
CODE: Remove Whitespace (ezpwd);
This commit is contained in:
@@ -28,10 +28,10 @@ namespace ezpwd {
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// output( <std::ostream> ) -- Output description of last failed test (or nothing if successful)
|
||||
// <std::ostream> << <asserter>
|
||||
//
|
||||
//
|
||||
std::ostream &output(
|
||||
std::ostream &lhs )
|
||||
const
|
||||
@@ -39,14 +39,14 @@ namespace ezpwd {
|
||||
return lhs << out;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// (bool) <asserter> -- Return status of last test
|
||||
//
|
||||
operator bool()
|
||||
{
|
||||
return failed;
|
||||
}
|
||||
|
||||
|
||||
template < typename T >
|
||||
asserter &istrue( const char *file, int line, const T &a, const std::string &comment = std::string() )
|
||||
{
|
||||
@@ -84,7 +84,7 @@ namespace ezpwd {
|
||||
}
|
||||
return success();
|
||||
}
|
||||
|
||||
|
||||
asserter &failure( const char *file, int line, const std::string &comparison,
|
||||
const std::string &comment = std::string() )
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2017, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -9,7 +9,7 @@
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. The Djelic BCH code
|
||||
* under djelic/ and the c++/ezpwd/bch_base wrapper is redistributed under the terms of the GPLv2+,
|
||||
* regardless of the overall licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "bch_base"
|
||||
|
||||
namespace ezpwd {
|
||||
//
|
||||
//
|
||||
// ezpwd::bch_base -- Interface to underlying Djelic Linux Kernel API
|
||||
// ezpwd::bch<SYMBOLS, CORRECTION> -- General BCH codec types; min. CORRECTION capacity, undefined PAYLOAD
|
||||
//
|
||||
@@ -31,7 +31,7 @@ namespace ezpwd {
|
||||
// target bit-error correction capacity T. They may correct more than T errors, and the number
|
||||
// of parity ECC bits will be selected by the algorithm. You need to compute the maximum
|
||||
// non-parity payload by computing _bch->n - _bch->ecc_bits.
|
||||
//
|
||||
//
|
||||
// The data and parity bits must always be on separate blocks of int8_t/uint8_t-sized data
|
||||
// in the container. This is required because the underlying API must break the data and parity
|
||||
// out as separate arrays for processing. So, if the computed ecc_bits is not evenly divisible
|
||||
@@ -39,12 +39,12 @@ namespace ezpwd {
|
||||
// the end of the supplied container. Alternatively, it can be kept in a separate container.
|
||||
// This is probably safest, as the bch_base/bch/BCH classes will never attempt to resize the
|
||||
// data/parity containers when supplied separately.
|
||||
//
|
||||
//
|
||||
// Like the Reed-Solomon APIs, the bch_base/bch/BCH APIs will alter the size of a variable
|
||||
// container in encode(...), to add the BCH ECC "parity" data (eg. std::vector, std::string).
|
||||
// Fixed containers (eg. std::array) are never resized, and it is assumed that ecc_bytes of
|
||||
// parity data exist at the end of the container.
|
||||
//
|
||||
//
|
||||
class bch_base {
|
||||
public:
|
||||
ezpwd::bch_control *_bch;
|
||||
@@ -92,12 +92,12 @@ namespace ezpwd {
|
||||
return lhs << *this->_bch;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// encode -- container interfaces
|
||||
//
|
||||
//
|
||||
// Returns number of ECC *bits* initialized (to be consistent w/ decode, which returns
|
||||
// number of bit errors corrected).
|
||||
//
|
||||
//
|
||||
int encode(
|
||||
std::string &data )
|
||||
const
|
||||
@@ -123,7 +123,7 @@ namespace ezpwd {
|
||||
return encode( cuTpair( (const uT *)&data.front(), (const uT *)&data.front() + data.size() ),
|
||||
uTpair( (uT *)&parity.front(), (uT *)&parity.front() + parity.size() ));
|
||||
}
|
||||
|
||||
|
||||
template < typename T >
|
||||
int encode(
|
||||
std::vector<T> &data )
|
||||
@@ -167,11 +167,11 @@ namespace ezpwd {
|
||||
return encode( uTpair( (uT *)&data.front() + pad, (uT *)&data.front() + data.size() ));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// encode -- denote data+parity or data, parity using pairs of uint8_t iterators
|
||||
// encode -- base implementation, in terms of uint8_t pointers
|
||||
//
|
||||
//
|
||||
virtual int encode(
|
||||
const std::pair<uint8_t *, uint8_t *>
|
||||
&data )
|
||||
@@ -206,9 +206,9 @@ namespace ezpwd {
|
||||
|
||||
//
|
||||
// decode -- container interface, w/ optional corrected bit-error positions reported
|
||||
//
|
||||
//
|
||||
// Does not correct errors in parity!
|
||||
//
|
||||
//
|
||||
int decode(
|
||||
std::string &data,
|
||||
std::vector<int> *position= 0 )
|
||||
@@ -280,15 +280,15 @@ namespace ezpwd {
|
||||
position );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// decode -- denote data+parity or data, parity using pairs of uint8_t iterators
|
||||
// decode -- decode and correct BCH codeword, returning number of corrections, or -1 if failed
|
||||
//
|
||||
//
|
||||
// Corrects data in-place (unlike the basic Djelic Linux Kernel API, which only returns
|
||||
// error positions. For consistency with ezpwd::rs..., we report all error positions as
|
||||
// std::vector<int>, even though the underlying Djelic API reports them as arrays of
|
||||
// unsigned int.
|
||||
//
|
||||
//
|
||||
virtual int decode(
|
||||
const std::pair<uint8_t *, uint8_t *>
|
||||
&data,
|
||||
@@ -329,18 +329,18 @@ namespace ezpwd {
|
||||
position->resize( corrects );
|
||||
return corrects;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// {en,de}coded -- returns an encoded/corrected copy of the provided container
|
||||
//
|
||||
// NOTE:
|
||||
//
|
||||
//
|
||||
// Must return exceptions on failure; If exceptions inhibited, returns a
|
||||
// default-constructed instance of the supplied data container. This may be sufficient to
|
||||
// reliably deduce failure; if not, this interface should not be used.
|
||||
//
|
||||
//
|
||||
// Overloads decoded to also allow recovery of corrected error positions and count.
|
||||
//
|
||||
//
|
||||
template <typename C>
|
||||
C encoded(
|
||||
C data )
|
||||
@@ -391,11 +391,11 @@ namespace ezpwd {
|
||||
}
|
||||
}; // class bch
|
||||
|
||||
//
|
||||
//
|
||||
// std::ostream << ezpwd::bch_base
|
||||
//
|
||||
//
|
||||
// Output a BCH codec description in standard form eg. BCH( 255, 239, 2 )
|
||||
//
|
||||
//
|
||||
inline
|
||||
std::ostream &operator<<(
|
||||
std::ostream &lhs,
|
||||
@@ -405,9 +405,9 @@ namespace ezpwd {
|
||||
return rhs.output( lhs );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::BCH<SYMBOLS, PAYLOAD, CAPACITY> -- Standard BCH codec types
|
||||
//
|
||||
//
|
||||
// Specify and create a standard BCH codec with exactly the specified capacities. We create
|
||||
// the undering BCH codec using SYMBOLS and CORRECTION capacity; the actual correction capacity
|
||||
// T, the number of PARITY bits and hence PAYLOAD (CAPACITY - PARITY) is selected automatically
|
||||
@@ -415,11 +415,11 @@ namespace ezpwd {
|
||||
// caller *knows* all of these values at compile time, however, mostly for future optimization
|
||||
// purposes. We validate them, and fail the constructor if they don't match. See bch_test for
|
||||
// an enumeration of all possible BCH codecs.
|
||||
//
|
||||
//
|
||||
// In the future, this API may be re-implemented to not use the generic BCH API, but a more
|
||||
// optimized locally-defined implementation that leverages the fixed SYMBOLS, PAYLOAD and
|
||||
// CORRECTION capacities to produce more optimal code.
|
||||
//
|
||||
//
|
||||
template < size_t SYMBOLS, size_t PAYLOAD, size_t CORRECTION >
|
||||
class BCH
|
||||
: public bch<SYMBOLS, CORRECTION>
|
||||
@@ -463,13 +463,13 @@ namespace ezpwd {
|
||||
}; // class BCH
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// std::ostream << ezpwd::BCH<...>
|
||||
//
|
||||
//
|
||||
// Output a BCH codec description in standard form eg. BCH( 255, 239, 2 )
|
||||
//
|
||||
//
|
||||
// NOTE: clang/gcc disagree on the scoping of operator<< template/non-template functions...
|
||||
//
|
||||
//
|
||||
template <size_t SYMBOLS, size_t PAYLOAD, size_t CORRECTION>
|
||||
inline
|
||||
std::ostream &operator<<(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2017, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -9,7 +9,7 @@
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. The Djelic BCH code
|
||||
* under djelic/ and the c++/ezpwd/bch_base wrapper is redistributed under the terms of the GPLv2+,
|
||||
* regardless of the overall licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
@@ -21,11 +21,11 @@
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
//
|
||||
// Presently, we simply import the Linux Kernel's "C" BCH API directly into the ezpwd:: namespace In
|
||||
// order to compile, you must (at least) run "make djelic" in the base directory of the
|
||||
// https://github.com/pjkundert/bch.git repo.
|
||||
//
|
||||
//
|
||||
namespace ezpwd {
|
||||
/**
|
||||
* struct bch_control - BCH control structure
|
||||
@@ -152,21 +152,21 @@ namespace ezpwd {
|
||||
#include "../../djelic_bch.h"
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// correct_bch -- corrects data (but not parity!), as suggested by decode_bch, above
|
||||
//
|
||||
//
|
||||
// A convenience interface that defaults all of the not strictly required parameters, and
|
||||
// automatically corrects bit-errors in data *and* the supplied parity. Does not attempt to
|
||||
// correct bit errors found in the parity data. If not supplied, 'errloc' is allocated
|
||||
// internally; otherwise, it is assumed to be of at least size bch->t (the minimum error
|
||||
// correction capacity of the BCH codec).
|
||||
//
|
||||
//
|
||||
// However, beware -- at larger values of T, the actual correction capacity of the BCH codec
|
||||
// could be greater than the requested T. Therefore, it is recommended that you always supply a
|
||||
// larger than required errloc array; recommend T*2?
|
||||
//
|
||||
//
|
||||
inline
|
||||
int correct_bch(
|
||||
int correct_bch(
|
||||
struct bch_control *bch,
|
||||
uint8_t *data,
|
||||
unsigned int len,
|
||||
@@ -198,9 +198,9 @@ namespace ezpwd {
|
||||
return err;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// <ostream> << <ezpwd::bch_control> -- output codec in standard BCH( N, N-ECC, T ) form
|
||||
//
|
||||
//
|
||||
inline
|
||||
std::ostream &operator<<(
|
||||
std::ostream &lhs,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2014, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -8,7 +8,7 @@
|
||||
* the License, or (at your option) any later version. See the LICENSE file at the top of the
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. c++/ezpwd/rs_base
|
||||
* is redistributed under the terms of the LGPL, regardless of the overall licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
namespace ezpwd {
|
||||
|
||||
//
|
||||
//
|
||||
// best_avg -- collect <password>,<confidence> guesses, and return the unambiguous best one
|
||||
//
|
||||
typedef std::map<std::string, std::pair<int, int>> // (<password>, (<count>, <avgsum>))
|
||||
@@ -38,9 +38,9 @@ namespace ezpwd {
|
||||
using best_avg_base_t::const_iterator;
|
||||
using best_avg_base_t::value_type;
|
||||
using best_avg_base_t::mapped_type;
|
||||
//
|
||||
//
|
||||
// add -- add the given pct to the current average for <string> str
|
||||
//
|
||||
//
|
||||
iterator add(
|
||||
const std::string &str,
|
||||
int pct )
|
||||
@@ -53,9 +53,9 @@ namespace ezpwd {
|
||||
return i;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// best -- return the unambiguously best value (average is >, or == but longer), or end()
|
||||
//
|
||||
//
|
||||
const_iterator best()
|
||||
const
|
||||
{
|
||||
@@ -76,11 +76,11 @@ namespace ezpwd {
|
||||
return uni ? top : end();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// evaluation -- process a (<password>,(<count>,<avgsum>)) into (<average>,<password>)
|
||||
// sort -- return a multimap indexed by <average> --> <string>
|
||||
// output -- output the <string>: <average>, sorted by average
|
||||
//
|
||||
//
|
||||
static std::pair<const int,const std::string &>
|
||||
evaluation( const value_type &val )
|
||||
{
|
||||
@@ -116,14 +116,14 @@ std::ostream &operator<<(
|
||||
}
|
||||
|
||||
namespace ezpwd {
|
||||
//
|
||||
//
|
||||
// ezpwd::corrector -- Apply statistical corrections to a string, returning the confidence
|
||||
//
|
||||
//
|
||||
// All methods are static; no instance is required, as this is primarily used to create
|
||||
// external language APIs.
|
||||
//
|
||||
//
|
||||
template <
|
||||
size_t PARITY,
|
||||
size_t PARITY,
|
||||
size_t N = 64,
|
||||
typename SERIAL = serialize::base< N, serialize::ezpwd< N >>>
|
||||
class corrector {
|
||||
@@ -135,10 +135,10 @@ namespace ezpwd {
|
||||
lhs << "corrector<PARITY=" << PARITY << ",N=" << N << ",SERIAL=" << SERIAL() << ">";
|
||||
return lhs;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// parity(<string>) -- Returns 'PARITY' base-N symbols of R-S parity to the supplied password
|
||||
//
|
||||
//
|
||||
static std::string parity(
|
||||
const std::string &password )
|
||||
{
|
||||
@@ -148,13 +148,13 @@ namespace ezpwd {
|
||||
return parity;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// encode(<string>) -- append PARITY base-N parity symbols to password
|
||||
//
|
||||
//
|
||||
// The supplied password buffer size must be sufficient to contain PARITY additional
|
||||
// symbols, plus the terminating NUL. Returns the resultant encoded password size
|
||||
// (excluding the NUL).
|
||||
//
|
||||
//
|
||||
static size_t encode(
|
||||
std::string &password )
|
||||
{
|
||||
@@ -178,23 +178,23 @@ namespace ezpwd {
|
||||
return len;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// decode(<string>[,...]) -- Applies R-S error correction on the encoded string, removing parity
|
||||
//
|
||||
//
|
||||
// Up to 'PARITY' Reed-Solomon parity symbols are examined, to determine if the supplied
|
||||
// string is a valid R-S codeword and hence very likely to be correct. Optionally supply a
|
||||
// vector of erasure positions.
|
||||
//
|
||||
//
|
||||
// An optional 'minimum' final password length may be provided; no R-S parity is assumed
|
||||
// to exist in the first 'minimum' password characters (default: PARITY). This prevents
|
||||
// accidentally finding valid R-S codewords in passwords of known minimum length; validation
|
||||
// codes, for example. Likewise, the optional 'maximum' allows us to limit the number of
|
||||
// parity symbols that may be assumed to be missing from the end of the codeword.
|
||||
//
|
||||
//
|
||||
// Returns a confidence strength rating, which is the ratio:
|
||||
//
|
||||
//
|
||||
// 100 - ( errors * 2 + erasures ) * 100 / parity
|
||||
//
|
||||
//
|
||||
// if an R-S codeword was solved, and 0 otherwise. If a codeword is solved, but the number
|
||||
// of errors and erasures corrected indicates that all parity was consumed, the caller may
|
||||
// opt to not use the corrected string, because there is a chance that our R-S polynomial
|
||||
@@ -204,26 +204,26 @@ namespace ezpwd {
|
||||
// were used in error/erasure recover, with none left to confirm that the result is actually
|
||||
// correct. If only zero-strength results are achieved, the longest will be returned (the
|
||||
// full, original string).
|
||||
//
|
||||
//
|
||||
// Supports the following forms of error/erasure:
|
||||
//
|
||||
//
|
||||
// 0) Full parity. All data and parity supplied, and an R-S codeword is solved.
|
||||
//
|
||||
//
|
||||
// 1) Partial parity. All data and some parity supplied; remainder are deemed erasures.
|
||||
//
|
||||
//
|
||||
// If PARITY > 2, then up to PARITY/2-1 trailing parity terms are marked as erasures.
|
||||
// If the R-S codeword is solved and a safe number of errors are found, then we can have
|
||||
// reasonable confidence that the string is correct.
|
||||
//
|
||||
//
|
||||
// 1a) Erase errors. Permute the combinations of up to PARITY-1 erasures.
|
||||
//
|
||||
//
|
||||
// o) Raw password. No parity terms supplied; not an R-S codeword
|
||||
//
|
||||
//
|
||||
// If none of the error/erasure forms succeed, the password is returned unmodified.
|
||||
//
|
||||
//
|
||||
// If a non-zero 'minimum' or 'maximum' are provided, they constrain the possible
|
||||
// resultant password sizes that will be attempted.
|
||||
//
|
||||
//
|
||||
static
|
||||
int decode(
|
||||
std::string &password,
|
||||
@@ -239,16 +239,16 @@ namespace ezpwd {
|
||||
// capability while maintaining at least one excess parity symbol for verification.
|
||||
// This can potentially result in longer password being returned, if the R-S decoder
|
||||
// accidentally solves a codeword.
|
||||
//
|
||||
//
|
||||
// For example, if PARITY=3 (or 4) then (PARITY+1)/2 == 2, and we would only attempt up
|
||||
// to 1 parity erasure. This would leave 1 parity symbol to replace the 1 erasure, and
|
||||
// 1 remaining to validate the integrity of the password.
|
||||
//
|
||||
//
|
||||
// The password must be long enough to contain at least 1 non-parity symbol, and the
|
||||
// designated number of non-erased parity symbols! However, by convention we'll demand
|
||||
// that the password contain at least PARITY symbols -- any less, and we can
|
||||
// accidentally correct the few remaining password symbols.
|
||||
//
|
||||
//
|
||||
// Also, if any parity symbols won't decode (eg. were entered in error), we must deem
|
||||
// them to be erasures, too, and if the number of erasures exceeds the capacity of the
|
||||
// R-S codec, it'll fail (throw an exception, or at best solve with 0 confidence).
|
||||
@@ -331,7 +331,7 @@ namespace ezpwd {
|
||||
<< " parity erasures " << std::setw( 3 ) << confidence
|
||||
<< "% confidence: \"" << password
|
||||
<< "\" ==> \"" << fixed
|
||||
<< "\" (corrects: " << corrects
|
||||
<< "\" (corrects: " << corrects
|
||||
<< ", erasures at " << all_era
|
||||
<< ", fixed at " << position << "): "
|
||||
<< std::endl
|
||||
@@ -354,7 +354,7 @@ namespace ezpwd {
|
||||
// w/ 3 parity: sock1tkeB
|
||||
// password ----^^^^^^
|
||||
// ^^^--- parity
|
||||
//
|
||||
//
|
||||
for ( size_t era = (PARITY+1)/2 // how many parity symbols are not present
|
||||
; era < PARITY
|
||||
; ++era ) {
|
||||
@@ -446,15 +446,15 @@ namespace ezpwd {
|
||||
return decode( password, std::vector<int>(), minimum, maximum );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// decode(<char*>,<size_t>,<size_t>,<size_t>) -- C interface to decode(<string>)
|
||||
//
|
||||
//
|
||||
// Traditional C interface. The provided NUL-terminated password+parity is decoded
|
||||
// (parity removed), and the confidence % is returned.
|
||||
//
|
||||
//
|
||||
// If any failure occurs, a -'ve value will be returned, and the supplied password
|
||||
// buffer will be used to contain an error description.
|
||||
//
|
||||
//
|
||||
static int decode(
|
||||
char *password, // NUL terminated
|
||||
size_t siz, // available size
|
||||
@@ -477,13 +477,13 @@ namespace ezpwd {
|
||||
return confidence;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// rscodec -- A ?-bit RS(N-1,N-1-PARITY) Reed-Solomon codec
|
||||
//
|
||||
//
|
||||
// Encodes and decodes R-S symbols over the lower 6 bits of the supplied data. Requires
|
||||
// that the last N (parity) symbols of the data are in the range [0,63]. The excess bits on
|
||||
// the data symbols are masked and restored during decoding.
|
||||
//
|
||||
//
|
||||
static const ezpwd::RS<N-1,N-1-PARITY>
|
||||
rscodec;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//
|
||||
//
|
||||
// C++ Definitions -- include once in a single C++ compilation unit
|
||||
//
|
||||
//
|
||||
#ifndef _EZPWD_DEFINITIONS
|
||||
#define _EZPWD_DEFINITIONS
|
||||
|
||||
|
||||
108
src/ezpwd/ezcod
108
src/ezpwd/ezcod
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2014, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -8,7 +8,7 @@
|
||||
* the License, or (at your option) any later version. See the LICENSE file at the top of the
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. c++/ezpwd/rs_base
|
||||
* is redistributed under the terms of the LGPL, regardless of the overall licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
@@ -25,9 +25,9 @@
|
||||
#include <ezpwd/output>
|
||||
#include <ezpwd/serialize>
|
||||
|
||||
//
|
||||
//
|
||||
// EZCOD 3:10 location code w/ Reed-Solomon Error Correction, and average 3m accuracy
|
||||
//
|
||||
//
|
||||
// - each successive symbol provides greater precision
|
||||
// - codes nearby each-other are identical in leading characters
|
||||
// - average 3m precision achieved in 9 symbols
|
||||
@@ -37,87 +37,87 @@
|
||||
// - 2 parity symbols provides correction of 1 lost symbol (no errors)
|
||||
// - 3 parity symbols provides correction of any 1 error, with verification,
|
||||
// or recovery of up to any 3 lost symbols (with no other errors)
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
//
|
||||
// To achieve at least 4 decimal digits of precision after the decimal point, we must have
|
||||
// defined lat to within 1 part in 1,800,000, and lon to within 1 part in 3,600,000. As each symbol
|
||||
// supplies bits, we'll refine the computed lat/lon further, reducing the outstanding fraction of
|
||||
// "parts" yet to be defined.
|
||||
//
|
||||
// bits
|
||||
//
|
||||
// bits
|
||||
// symbols latitude longitude
|
||||
// bits mul parts bits mul parts
|
||||
// 1 2 4 4 3 8 8
|
||||
// 2 2 4 16 3 8 64
|
||||
// 3 3 8 128 2 4 256 // not quite integer lat/lon accuracy
|
||||
//
|
||||
//
|
||||
// 4 2 4 512 3 8 2,048
|
||||
// 5 3 8 4,096 2 4 8,192
|
||||
// 6 2 4 16,384 3 8 65,536
|
||||
// 6 2 4 16,384 3 8 65,536
|
||||
//
|
||||
// 7 3 8 131,072 2 4 262,144
|
||||
// 8 2 4 524,288 3 8 2,097,152
|
||||
// 9 3 8 4,194,304 2 4 8,388,608 parts resolution in 3:10 code
|
||||
// over [-90, 90] over [-180,180] yields ~3m resolution
|
||||
//
|
||||
//
|
||||
// vs. 1,800,000 3,600,000 parts resolution in 10:10 code
|
||||
// over [-90, 90] over [-180,180] yields ~10m resolution
|
||||
//
|
||||
//
|
||||
// Therefore, within 9 symbols we define lat and lon with better than double the precision of
|
||||
// 10:10 code's 4 decimal digits after the decimal point. This yields an approximate lineal
|
||||
// precision of 40,075,000m / 8,388,608 == ~5m in both dimensions at the equator, vs. 40,075,000m /
|
||||
// 3,600,000 == ~11m for 10:10 codes.
|
||||
//
|
||||
//
|
||||
// The 10:10 code provides a single check character, which provides about P(1-1/32) certainty
|
||||
// that the provided code is correct. With EZCOD 3:10/11/12 codes, we provide varying levels of
|
||||
// that the provided code is correct. With EZCOD 3:10/11/12 codes, we provide varying levels of
|
||||
// detection/correction strength.
|
||||
//
|
||||
//
|
||||
// - 1 parity symbol: act as a check character (like 10:10 codes), or provide 1 symbol of erasure
|
||||
// (lost symbol) recovery with no excess parity for validation.
|
||||
//
|
||||
//
|
||||
// - 2 parity symbols: provide 1 symbol of erasure correction (w/ no other errors) with 1 excess parity
|
||||
// symbol for validation, or 1 symbol of error detection with no excess parity for validation.
|
||||
//
|
||||
//
|
||||
// - 3 parity symbols: correct 1 error anywhere w/ 1 excess parity symbol for validation, or up
|
||||
// to 3 erasures with no excess parity for validation.
|
||||
//
|
||||
//
|
||||
// Therefore, we'll provide Reed-Solomon RS(31,28-30) error correction (5 bit symbols,
|
||||
// indicating 31 symbols in the field, and from 1 to 3 roots, therefore up to 28 data symbols in the
|
||||
// field) over the 9 lat/lon data symbols.
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// MINIMIZING ERROR
|
||||
//
|
||||
//
|
||||
// Each input lat/lon coordinate will be effectively truncated by the encoding procedure to the
|
||||
// level of precision (parts) encoded by each symbol. Subsequent symbols then add their (smaller)
|
||||
// parts to increase precision.
|
||||
//
|
||||
//
|
||||
// After the last symbol, we know that the actual input coordinates where somewhere
|
||||
// within the rectangle:
|
||||
//
|
||||
//
|
||||
// [0,0] -> [0,lon_precision] -> [lat_precision,lon_precision] -> [lat_precision,0]
|
||||
//
|
||||
//
|
||||
// At first glance, the best way is to perform rounding instead of truncation on ecoding, by
|
||||
// simply adding 1/2 of the precision. Then, the unmodified output lat/lon decoded represents the
|
||||
// point nearest actual input coordinate. However, this is NOT ideal. Remember -- the decoding may
|
||||
// not have access to all the symbols! We want to minimize the error even if only some of the
|
||||
// symbols are available. Thus, we must apply a correction on decoding.
|
||||
//
|
||||
//
|
||||
// One way gain rounding instead of truncation on decoding is, after adding the last symbol's
|
||||
// precision, to add 50% of the value represented by the first bit of the next (missing) symbol's
|
||||
// precision parts. This would be analogous to receiving the first 2 digits of a 3 digit number:
|
||||
//
|
||||
//
|
||||
// original: 123
|
||||
// received: 12_
|
||||
// range: [120,130)
|
||||
// guessed: 125 (add 1/2 of the parts represented by the missing digit)
|
||||
//
|
||||
//
|
||||
// If this is done, then the resulting coordinate would be in the middle of the rectangle of
|
||||
// possible input lat/lon values that could have resulted in the encoded value. This also works if
|
||||
// we don't receive and decode all of the symbols; We'll end up with a lat/lon in the middle of the
|
||||
// (large) rectangle of possible input coordinates.
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
namespace ezpwd {
|
||||
@@ -179,9 +179,9 @@ inline std::ostream &operator<<(
|
||||
|
||||
namespace ezpwd {
|
||||
|
||||
//
|
||||
//
|
||||
// ezcod<P,L> -- defaults to 1 PARITY and 9 location symbols (3m) of PRECISION
|
||||
//
|
||||
//
|
||||
template < unsigned P=1, unsigned L=9 >
|
||||
class ezcod
|
||||
: public ezcod_base {
|
||||
@@ -221,9 +221,9 @@ namespace ezpwd {
|
||||
char separator; // Separator between location and parity symbols
|
||||
char space; // Fill space between location symbol chunks
|
||||
|
||||
//
|
||||
//
|
||||
// ezcod<P,L>() -- supply non-defaults for location precision, chunk size, etc.
|
||||
//
|
||||
//
|
||||
explicit ezcod(
|
||||
double _lat = 0,
|
||||
double _lon = 0,
|
||||
@@ -261,7 +261,7 @@ namespace ezpwd {
|
||||
|
||||
//
|
||||
// symbols -- return working parity and location precision
|
||||
//
|
||||
//
|
||||
virtual ezcod_base::symbols_t
|
||||
symbols()
|
||||
const
|
||||
@@ -302,9 +302,9 @@ namespace ezpwd {
|
||||
return lhs;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// encode() -- encode the lat/lon to 'precision' symbols EZCOD representation
|
||||
//
|
||||
//
|
||||
virtual std::string encode(
|
||||
unsigned _preci = 0 ) // override precision
|
||||
const
|
||||
@@ -400,50 +400,50 @@ namespace ezpwd {
|
||||
return res;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// deserialize -- Extract base-32, skip whitespace, mark invalid symbols as erasures
|
||||
// validate -- Remove base-32 encoding, validate and remove parity, returning confidence
|
||||
// decode -- Attempt to decode a lat/lon, returning the confidence percentage
|
||||
//
|
||||
//
|
||||
// If data but no parity symbols are supplied, no error checking is performed, and the
|
||||
// confidence returned will be 0%. No erasures within the supplied data are allowed (as
|
||||
// there is no capacity to correct them), and an exception will be thrown.
|
||||
//
|
||||
//
|
||||
// If parity is supplied, then erasures are allowed. So long as the total number of
|
||||
// erasures is <= the supplied parity symbols, then the decode will proceed (using the
|
||||
// parity symbols to fill in the erasures), and the returned confidence will reflect the
|
||||
// amount of unused parity capacity. Each erasure consumes one parity symbol to repair.
|
||||
//
|
||||
//
|
||||
// We'll allow question-mark or any of the slash characters: "_/\?" to indicate an
|
||||
// erasure. Either of the "!." symbol may be used to indicates the split between location
|
||||
// symbols and parity symbols, and must be in a position that corresponds to the indicated
|
||||
// number of location (this->precision) and parity 'P' symbols. Whitespace symbols and dash
|
||||
// are ignored: " -".
|
||||
//
|
||||
//
|
||||
// Thus, an EZCOD like "R3U 1JU QUY!0" may only be decoded by an ezcod<P=1>. Without
|
||||
// the "!" or ".", it could be an ezcod<P=2> w/precision == 8 -- there's no way to know for
|
||||
// sure. If no explicit position-parity separator is given, then we assume the default:
|
||||
// this->precision location symbols, then up to P parity symbols. If additional parity
|
||||
// symbols are supplied after the separator, then However, an ezcod...<P=3>
|
||||
//
|
||||
//
|
||||
// If an explicit "!" or "." separator IS provided, then we will attempt to decode the
|
||||
// position with the given number of position symbols, and up to P parity symbols.
|
||||
//
|
||||
//
|
||||
// NOTE
|
||||
//
|
||||
//
|
||||
// Due to a perhaps unexpected feature of R-S codewords, a codeword with MORE parity
|
||||
// can be successfully decoded by an R-S codec specifying LESS parity symbols. It so
|
||||
// happens that the data plus (excess) parity + (remaining) parity is STILL a valid codeword
|
||||
// (so long as the R-S Galois parameters are identical).
|
||||
//
|
||||
//
|
||||
// Therefore, EZCODs with more parity are accepted by EZCOD parsers configured for less
|
||||
// parity. Of course, they will have less error/erasure correction strength -- using the
|
||||
// correctly configured EZCOD codec expecting more R-S parity will maximize the value of all
|
||||
// the supplied parity.
|
||||
//
|
||||
//
|
||||
// The full amount of parity (ie. everything after the location/parity separator) is
|
||||
// discarded in all cases, before the EZCOD location is decoded.
|
||||
//
|
||||
//
|
||||
private:
|
||||
|
||||
unsigned deserialize(
|
||||
@@ -627,20 +627,20 @@ namespace ezpwd {
|
||||
// Compute the resolution error (in m.) of the decoded lat/lon and compute the minimum
|
||||
// accuracy -- the radius of the circle around the computed latitude/longitude, inside
|
||||
// which the original latitude/longitude must have been.
|
||||
//
|
||||
//
|
||||
// original latitude error bar
|
||||
// \ /
|
||||
// o -
|
||||
// o -
|
||||
// | longitude error bar
|
||||
// | /
|
||||
// |--x--|
|
||||
// |--x--|
|
||||
// /|
|
||||
// / |
|
||||
// computed -
|
||||
//
|
||||
//
|
||||
// The maximum distance is the length of the diagonal of the error rectangle defined by
|
||||
// 1/2 the latitude/longitude error bars.
|
||||
//
|
||||
//
|
||||
double lon_circ= 1 * M_PI * 6371000;
|
||||
double lat_circ= 2 * M_PI * 6371000 * std::cos( latitude * M_PI / 180 );
|
||||
latitude_error = lat_err * lon_circ;
|
||||
@@ -653,13 +653,13 @@ namespace ezpwd {
|
||||
}; // class ezcod
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// ezcod::rscodec -- Reed-Solomon parity codec
|
||||
// ezcod::bits -- distribution of lat/lon precision in each code symbol
|
||||
//
|
||||
//
|
||||
// Quickly establishes an extra bit of precision for Longitude, and then evenly distributes
|
||||
// future precision between lat/lon, always maintaining extra precision for Longitude.
|
||||
//
|
||||
//
|
||||
template < unsigned P, unsigned L >
|
||||
const ezpwd::RS<31,31-P> ezcod<P,L>::rscodec;
|
||||
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::hexchr -- escape/hexify char c, output using func/meth f, in width w >= 2
|
||||
// ezpwd::hexify -- hexify something that can be converted to an unsigned char
|
||||
// ezpwd::hexout -- hexify each element in the range (beg,end], limited by stream's width
|
||||
//
|
||||
//
|
||||
// std::ostream << ezpwd::hexify( c ) // output any char escaped/hex
|
||||
// std::ostream << ezpwd::hexout( beg, end ) // output any char iterator to ostream
|
||||
// std::ostream << std::vector<unsigend char>
|
||||
// std::ostream << std::array<unsigend char, N>
|
||||
// ezpwd::hexchr( c, [](unsigned char c){...;} )// output escaped/hex char via functor
|
||||
// ezpwd::hexout( beg, end, FILE* ) // output any char iterator to FILE*
|
||||
//
|
||||
//
|
||||
// Output unprintable unsigned char data in hex, escape printable/whitespace data.
|
||||
//
|
||||
namespace ezpwd {
|
||||
@@ -152,19 +152,19 @@ namespace std {
|
||||
return ezpwd::hexout( lhs, rhs.begin(), rhs.end() );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// <ostream&> << pair<T,U>
|
||||
// <ostream&> << set<T> -- sorted by T
|
||||
// <ostream&> << map<T,U> -- sorted by T (key)
|
||||
// <ostream&> << vector<T>
|
||||
//
|
||||
//
|
||||
// Handle output of various container types.
|
||||
//
|
||||
//
|
||||
// Output pairs and sets of pairs, respecting specified widths (as appropriate). For example
|
||||
// a set of pairs of integeters 's', if output as "... << std::setw( 13 ) << s;", would yield:
|
||||
//
|
||||
//
|
||||
// ( 1, 2) ( 3, 4) ...
|
||||
//
|
||||
//
|
||||
|
||||
template <class T, class U>
|
||||
std::ostream &operator<<(
|
||||
@@ -174,8 +174,8 @@ namespace std {
|
||||
std::streamsize w = std::max( std::streamsize( 0 ),
|
||||
std::streamsize( lhs.width() - 3 ));
|
||||
lhs << std::setw( 0 )
|
||||
<< '(' << std::setw( w / 2 ) << rhs.first
|
||||
<< ',' << std::setw( w - w / 2 ) << rhs.second
|
||||
<< '(' << std::setw( w / 2 ) << rhs.first
|
||||
<< ',' << std::setw( w - w / 2 ) << rhs.second
|
||||
<< ')';
|
||||
return lhs;
|
||||
}
|
||||
@@ -190,7 +190,7 @@ namespace std {
|
||||
si = rhs.begin()
|
||||
; si != rhs.end()
|
||||
; ++si ) {
|
||||
if ( si != rhs.begin())
|
||||
if ( si != rhs.begin())
|
||||
lhs << ' ';
|
||||
lhs << std::setw( w ) << *si;
|
||||
}
|
||||
@@ -215,7 +215,7 @@ std::ostream &operator<<(
|
||||
ki = key.begin()
|
||||
; ki != key.end()
|
||||
; ++ki ) {
|
||||
if ( ki != key.begin())
|
||||
if ( ki != key.begin())
|
||||
lhs << ' ';
|
||||
lhs << std::setw( w ) << *rhs.find( *ki );
|
||||
}
|
||||
@@ -225,7 +225,7 @@ std::ostream &operator<<(
|
||||
|
||||
template <class T>
|
||||
std::ostream &operator<<(
|
||||
std::ostream &lhs,
|
||||
std::ostream &lhs,
|
||||
const std::vector<T> &rhs )
|
||||
{
|
||||
for( size_t i = 0; i < rhs.size(); ++i ) {
|
||||
@@ -238,20 +238,20 @@ std::ostream &operator<<(
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::buf_t -- describe a C string buffer, to allow C++ output operations
|
||||
// ezpwd::streambuf_to_buf_t -- output charcters, always NUL terminated
|
||||
//
|
||||
//
|
||||
// <buf_t> << ... -- Copy the <string> into the C <char*,size_t> buffer, always NUL terminating
|
||||
//
|
||||
//
|
||||
// Copies <string> contents into buffer, and always NUL-terminates. Returns advanced buf_t (NOT
|
||||
// including the terminating NUL, suitable for repeating ... << <string> operations.
|
||||
//
|
||||
//
|
||||
// std::ostream( &<streambuf_to_buf_t> ) << ...
|
||||
//
|
||||
//
|
||||
// Use standard ostream operations to send output to a C buffer, always NUL
|
||||
// terminating, and never exceeding capacity.
|
||||
//
|
||||
//
|
||||
namespace ezpwd {
|
||||
|
||||
typedef std::pair<char *,size_t>
|
||||
@@ -266,7 +266,7 @@ namespace ezpwd {
|
||||
//
|
||||
// streambuf_to_buf_t -- remember buf_t details
|
||||
// ~streambuf_to_buf_t -- no virtual destructor required; nothing to clean up
|
||||
//
|
||||
//
|
||||
streambuf_to_buffer(
|
||||
char *buf,
|
||||
size_t siz )
|
||||
@@ -282,10 +282,10 @@ namespace ezpwd {
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// overflow -- Append c, always NUL terminating
|
||||
//
|
||||
//
|
||||
virtual int overflow(
|
||||
int c )
|
||||
{
|
||||
@@ -322,12 +322,12 @@ namespace std {
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// <std::string> << ...
|
||||
//
|
||||
//
|
||||
// Useful (but inefficient) standard output formatting directly to a std::string. Use only for
|
||||
// testing code, for efficiency reasons...
|
||||
//
|
||||
//
|
||||
template < typename T >
|
||||
inline
|
||||
std::string operator<<(
|
||||
|
||||
42
src/ezpwd/rs
42
src/ezpwd/rs
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2014, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -8,7 +8,7 @@
|
||||
* the License, or (at your option) any later version. See the LICENSE file at the top of the
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. c++/ezpwd/rs_base
|
||||
* is redistributed under the terms of the LGPL, regardless of the overall licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
@@ -18,31 +18,31 @@
|
||||
|
||||
#include "rs_base"
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::RS<SYMBOLS,PAYLOAD> -- Implements an RS(SYMBOLS,PAYLOAD) codec
|
||||
// ezpwd::RS_CCSDS<...> -- CCSDS standard 8-bit R-S codec
|
||||
//
|
||||
//
|
||||
// Support for Reed-Solomon codecs for symbols of 2 to 16 bits is supported. The R-S "codeword"
|
||||
// for an N-bit symbol is defined to be 2^N-1 symbols in size. For example, for 5-bit symbols,
|
||||
// 2^5-1 == 31, so the notation for defining an Reed-Solomon codec for 5-bit symbols is always:
|
||||
// RS(31,PAYLOAD), where PAYLOAD is always some value less than 31. The difference is the number of
|
||||
// "parity" symbols.
|
||||
//
|
||||
//
|
||||
// For example, to define an RS codeword of 31 symbols w/ 4 symbols of parity and up to 27
|
||||
// symbols of data, you would say: RS(31,27). Of course, you can supply smaller amounts of data;
|
||||
// the balance is assumed to be NUL (zero) symbols.
|
||||
//
|
||||
//
|
||||
namespace ezpwd {
|
||||
|
||||
//
|
||||
// __RS( ... ) -- Define a reed-solomon codec
|
||||
//
|
||||
//
|
||||
// __RS( ... ) -- Define a reed-solomon codec
|
||||
//
|
||||
// @SYMBOLS: Total number of symbols; must be a power of 2 minus 1, eg 2^8-1 == 255
|
||||
// @PAYLOAD: The maximum number of non-parity symbols, eg 253 ==> 2 parity symbols
|
||||
// @POLY: A primitive polynomial appropriate to the SYMBOLS size
|
||||
// @FCR: The first consecutive root of the Reed-Solomon generator polynomial
|
||||
// @PRIM: The primitive root of the generator polynomial
|
||||
//
|
||||
//
|
||||
# define __RS_TYP( TYPE, SYMBOLS, PAYLOAD, POLY, FCR, PRIM ) \
|
||||
ezpwd::reed_solomon< \
|
||||
TYPE, \
|
||||
@@ -66,10 +66,10 @@ namespace ezpwd {
|
||||
// standard Reed-Solomon codecs using macros of a similar form, eg. RS<255, 252>. Standard PLY,
|
||||
// FCR and PRM values are provided for various SYMBOL sizes, along with appropriate basic types
|
||||
// capable of holding all internal Reed-Solomon tabular data.
|
||||
//
|
||||
//
|
||||
// In order to provide "default initialization" of const RS<...> types, a user-provided
|
||||
// default constructor must be provided.
|
||||
//
|
||||
//
|
||||
template < size_t SYMBOLS, size_t PAYLOAD > struct RS;
|
||||
template < size_t PAYLOAD > struct RS< 3, PAYLOAD> : public __RS( RS, uint8_t, 3, PAYLOAD, 0x7, 1, 1 );
|
||||
template < size_t PAYLOAD > struct RS< 7, PAYLOAD> : public __RS( RS, uint8_t, 7, PAYLOAD, 0xb, 1, 1 );
|
||||
@@ -86,29 +86,29 @@ namespace ezpwd {
|
||||
template < size_t PAYLOAD > struct RS<16383, PAYLOAD> : public __RS( RS, uint16_t, 16383, PAYLOAD, 0x4443, 1, 1 );
|
||||
template < size_t PAYLOAD > struct RS<32767, PAYLOAD> : public __RS( RS, uint16_t, 32767, PAYLOAD, 0x8003, 1, 1 );
|
||||
template < size_t PAYLOAD > struct RS<65535, PAYLOAD> : public __RS( RS, uint16_t, 65535, PAYLOAD, 0x1100b, 1, 1 );
|
||||
|
||||
|
||||
template < size_t SYMBOLS, size_t PAYLOAD > struct RS_CCSDS;
|
||||
template < size_t PAYLOAD > struct RS_CCSDS<255, PAYLOAD> : public __RS( RS_CCSDS, uint8_t, 255, PAYLOAD, 0x187, 112, 11 );
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// strength<PARITY> -- compute strength (given N parity symbols) of R-S correction
|
||||
//
|
||||
//
|
||||
// Returns a confidence strength rating, which is the ratio:
|
||||
//
|
||||
//
|
||||
// 100 - ( errors * 2 + erasures ) * 100 / parity
|
||||
//
|
||||
//
|
||||
// which is proportional to the number of parity symbols unused by the reported number of
|
||||
// corrected symbols. If 0, then all parity resources were consumed to recover the R-S
|
||||
// codeword, and we can have no confidence in the result. If -'ve, indicates more parity
|
||||
// resources were consumed than available, indicating that the result is likely incorrect.
|
||||
//
|
||||
//
|
||||
// Accounts for the fact that a signalled erasure may not be reported in the corrected
|
||||
// position vector, if the symbol happens to match the computed value. Note that even if the
|
||||
// error or erasure occurs within the "parity" portion of the codeword, this doesn't reduce the
|
||||
// effective strength -- all symbols in the R-S complete codeword are equally effective in
|
||||
// recovering any other symbol in error/erasure.
|
||||
//
|
||||
//
|
||||
template < size_t PARITY >
|
||||
int strength(
|
||||
int corrected,
|
||||
@@ -162,7 +162,7 @@ namespace ezpwd {
|
||||
#endif
|
||||
return confidence;
|
||||
}
|
||||
|
||||
|
||||
} // namespace ezpwd
|
||||
|
||||
|
||||
#endif // _EZPWD_RS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2014, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -9,43 +9,43 @@
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. The
|
||||
* c++/ezpwd/rs_base file is redistributed under the terms of the LGPL, regardless of the overall
|
||||
* licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* The core Reed-Solomon codec implementation in c++/ezpwd/rs_base is by Phil Karn, converted to C++
|
||||
* by Perry Kundert (perry@hardconsulting.com), and may be used under the terms of the LGPL. Here
|
||||
* is the terms from Phil's README file (see phil-karn/fec-3.0.1/README):
|
||||
*
|
||||
*
|
||||
* COPYRIGHT
|
||||
*
|
||||
*
|
||||
* This package is copyright 2006 by Phil Karn, KA9Q. It may be used
|
||||
* under the terms of the GNU Lesser General Public License (LGPL). See
|
||||
* the file "lesser.txt" in this package for license details.
|
||||
*
|
||||
*
|
||||
* The c++/ezpwd/rs_base file is, therefore, redistributed under the terms of the LGPL, while the
|
||||
* rest of Ezpwd Reed-Solomon is distributed under either the GPL or Commercial licenses.
|
||||
* Therefore, even if you have obtained Ezpwd Reed-Solomon under a Commercial license, you must make
|
||||
* available the source code of the c++/ezpwd/rs_base file with your product. One simple way to
|
||||
* accomplish this is to include the following URL in your code or documentation:
|
||||
*
|
||||
*
|
||||
* https://github.com/pjkundert/ezpwd-reed-solomon/blob/master/c++/ezpwd/rs_base
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* The Linux 3.15.1 version of lib/reed_solomon was also consulted as a cross-reference, which (in
|
||||
* turn) is basically verbatim copied from Phil Karn's LGPL implementation, to ensure that no new
|
||||
* defects had been found and fixed; there were no meaningful changes made to Phil's implementation.
|
||||
* I've personally been using Phil's implementation for years in a heavy industrial use, and it is
|
||||
* rock-solid.
|
||||
*
|
||||
*
|
||||
* However, both Phil's and the Linux kernel's (copy of Phil's) implementation will return a
|
||||
* "corrected" decoding with impossible error positions, in some cases where the error load
|
||||
* completely overwhelms the R-S encoding. These cases, when detected, are rejected in this
|
||||
* implementation. This could be considered a defect in Phil's (and hence the Linux kernel's)
|
||||
* implementations, which results in them accepting clearly incorrect R-S decoded values as valid
|
||||
* (corrected) R-S codewords. We chose the report failure on these attempts.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#ifndef _EZPWD_RS_BASE
|
||||
#define _EZPWD_RS_BASE
|
||||
@@ -58,14 +58,14 @@
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
//
|
||||
// Preprocessor defines available:
|
||||
//
|
||||
//
|
||||
// EZPWD_NO_EXCEPTS -- define to use no exceptions; return -1, or abort on catastrophic failures
|
||||
// EZPWD_NO_MOD_TAB -- define to force no "modnn" Galois modulo table acceleration
|
||||
// EZPWD_ARRAY_SAFE -- define to force usage of bounds-checked arrays for most tabular data
|
||||
// EZPWD_ARRAY_TEST -- define to force erroneous sizing of some arrays for non-production testing
|
||||
//
|
||||
//
|
||||
|
||||
#if defined( DEBUG ) && DEBUG >= 2
|
||||
# include "output" // ezpwd::hex... std::ostream shims for outputting containers of uint8_t data
|
||||
@@ -117,35 +117,35 @@ namespace ezpwd {
|
||||
return lhs << "RS(" << this->size() << "," << this->load() << ")";
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// {en,de}code -- Compute/Correct errors/erasures in a Reed-Solomon encoded container
|
||||
//
|
||||
//
|
||||
/// The encoded parity symbols may be included in 'data' (len includes nroots() parity
|
||||
/// symbols), or may (optionally) supplied separately in (at least nroots()-sized)
|
||||
/// 'parity'.
|
||||
///
|
||||
/// 'parity'.
|
||||
///
|
||||
/// For decode, optionally specify some known erasure positions (up to nroots()). If
|
||||
/// non-empty 'erasures' is provided, it contains the positions of each erasure. If a
|
||||
/// non-zero pointer to a 'position' vector is provided, its capacity will be increased to
|
||||
/// be capable of storing up to 'nroots()' ints; the actual deduced error locations will be
|
||||
/// returned.
|
||||
///
|
||||
///
|
||||
/// RETURN VALUE
|
||||
///
|
||||
///
|
||||
/// Return -1 on error. The encode returns the number of parity symbols produced;
|
||||
/// decode returns the number of symbols corrected. Both errors and erasures are included,
|
||||
/// so long as they are actually different than the deduced value. In other words, if a
|
||||
/// symbol is marked as an erasure but it actually turns out to be correct, it's index will
|
||||
/// NOT be included in the returned count, nor the modified erasure vector!
|
||||
///
|
||||
///
|
||||
|
||||
//
|
||||
//
|
||||
// encode(<string>) -- extend string to contain parity, or place in supplied parity string
|
||||
// encode(<vector>) -- extend vector to contain parity, or place in supplied parity vector
|
||||
// encode(<array>) -- ignore 'pad' elements of array, puts nroots() parity symbols at end
|
||||
// encode(pair<iter,iter>) -- encode all except the last nroots() of the data, put parity at end
|
||||
// encode(pair<iter,iter>, pair<iter,iter>) -- encode data between first <iter> pair, put parity in second pair
|
||||
//
|
||||
//
|
||||
int encode(
|
||||
std::string &data )
|
||||
const
|
||||
@@ -388,11 +388,11 @@ namespace ezpwd {
|
||||
= 0;
|
||||
}; // class reed_solomon_base
|
||||
|
||||
//
|
||||
//
|
||||
// std::ostream << ezpwd::reed_solomon<...>
|
||||
//
|
||||
//
|
||||
// Output a R-S codec description in standard form eg. RS(255,253)
|
||||
//
|
||||
//
|
||||
inline
|
||||
std::ostream &operator<<(
|
||||
std::ostream &lhs,
|
||||
@@ -421,10 +421,10 @@ namespace ezpwd {
|
||||
return sr;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
//
|
||||
// class reed_solomon_tabs -- R-S tables common to all RS(NN,*) with same SYM, PRM and PLY
|
||||
//
|
||||
//
|
||||
template < typename TYP, int SYM, int PRM, class PLY >
|
||||
class reed_solomon_tabs
|
||||
: public reed_solomon_base {
|
||||
@@ -501,7 +501,7 @@ namespace ezpwd {
|
||||
iprim = iptmp / PRM;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// modnn -- modulo replacement for galois field arithmetics, optionally w/ table acceleration
|
||||
//
|
||||
// @x: the value to reduce (will never be -'ve)
|
||||
@@ -555,7 +555,7 @@ namespace ezpwd {
|
||||
// All reed_solomon<T, ...> instances with the same template type parameters share a common
|
||||
// (static) set of alpha_to, index_of and genpoly tables. The first instance to be constructed
|
||||
// initializes the tables.
|
||||
//
|
||||
//
|
||||
// Each specialized type of reed_solomon implements a specific encode/decode method
|
||||
// appropriate to its datum 'TYP'. When accessed via a generic reed_solomon_base pointer, only
|
||||
// access via "safe" (size specifying) containers or iterators is available.
|
||||
@@ -722,7 +722,7 @@ namespace ezpwd {
|
||||
}
|
||||
return NROOTS;
|
||||
}
|
||||
|
||||
|
||||
using reed_solomon_base::decode;
|
||||
virtual int decode(
|
||||
const std::pair<uint8_t *, uint8_t *>
|
||||
@@ -811,14 +811,14 @@ namespace ezpwd {
|
||||
erasure, position );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// decode_mask -- mask INP data into valid SYMBOL data
|
||||
//
|
||||
//
|
||||
/// Incoming data may be in a variety of sizes, and may contain information beyond the
|
||||
/// R-S symbol capacity. For example, we might use a 6-bit R-S symbol to correct the lower
|
||||
/// 6 bits of an 8-bit data character. This would allow us to correct common substitution
|
||||
/// errors (such as '2' for '3', 'R' for 'T', 'n' for 'm').
|
||||
///
|
||||
///
|
||||
template < typename INP >
|
||||
int decode_mask(
|
||||
INP *data,
|
||||
@@ -1078,7 +1078,7 @@ namespace ezpwd {
|
||||
#if DEBUG >= 1
|
||||
// Test code that verifies the erasure locator polynomial just constructed
|
||||
// Needed only for decoder debugging.
|
||||
|
||||
|
||||
// find roots of the erasure location polynomial
|
||||
for( int i = 1; i<= no_eras; i++ )
|
||||
reg[i] = index_of[lambda[i]];
|
||||
@@ -1100,7 +1100,7 @@ namespace ezpwd {
|
||||
count++;
|
||||
}
|
||||
if ( count != no_eras ) {
|
||||
std::cout << "ERROR: count = " << count << ", no_eras = " << no_eras
|
||||
std::cout << "ERROR: count = " << count << ", no_eras = " << no_eras
|
||||
<< "lambda(x) is WRONG"
|
||||
<< std::endl;
|
||||
count = -1;
|
||||
@@ -1309,12 +1309,12 @@ namespace ezpwd {
|
||||
}
|
||||
}; // class reed_solomon
|
||||
|
||||
//
|
||||
//
|
||||
// Define the static reed_solomon...<...> members; allowed in header for template types.
|
||||
//
|
||||
//
|
||||
// The reed_solomon_tags<...>::iprim < 0 is used to indicate to the first instance that the
|
||||
// static tables require initialization.
|
||||
//
|
||||
//
|
||||
template < typename TYP, int SYM, int PRM, class PLY >
|
||||
int reed_solomon_tabs< TYP, SYM, PRM, PLY >::iprim = -1;
|
||||
|
||||
@@ -1340,5 +1340,5 @@ namespace ezpwd {
|
||||
reed_solomon< TYP, SYM, RTS, FCR, PRM, PLY >::genpoly;
|
||||
|
||||
} // namespace ezpwd
|
||||
|
||||
|
||||
#endif // _EZPWD_RS_BASE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Ezpwd Reed-Solomon -- Reed-Solomon encoder / decoder library
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2014, Hard Consulting Corporation.
|
||||
*
|
||||
* Ezpwd Reed-Solomon is free software: you can redistribute it and/or modify it under the terms of
|
||||
@@ -8,7 +8,7 @@
|
||||
* the License, or (at your option) any later version. See the LICENSE file at the top of the
|
||||
* source tree. Ezpwd Reed-Solomon is also available under Commercial license. c++/ezpwd/rs_base
|
||||
* is redistributed under the terms of the LGPL, regardless of the overall licensing terms.
|
||||
*
|
||||
*
|
||||
* Ezpwd Reed-Solomon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
* the GNU General Public License for more details.
|
||||
@@ -21,29 +21,29 @@
|
||||
|
||||
#include "output"
|
||||
|
||||
//
|
||||
//
|
||||
// EZPWD (no padding) and RFC4648 (enforce padding) base-N codecs
|
||||
//
|
||||
//
|
||||
// scatter -- 8-bit binary data into 5-bit (base32) and 6-bit (base64) chunks (optionally w/pad)
|
||||
// gather -- collect up 5/6-bit binary data back into 8-bit characters (optionally w/pad)
|
||||
// ..._standard -- enforce RFC4648-standard padding
|
||||
//
|
||||
//
|
||||
// Scatters or gathers 8-bit binary character data to 5/6-bit symbols, suitable for base32/64
|
||||
// encoding.
|
||||
//
|
||||
//
|
||||
// encode -- convert binary data to ASCII base32/64, in-place
|
||||
// decode -- convert ASCII base32/64 to binary data, in-place
|
||||
// ..._standard -- enforce RFC4648-standard padding
|
||||
//
|
||||
//
|
||||
// Transforms iterable containers of char between ASCII symbols and binary data, always in-place.
|
||||
// The decode may alter the size of the result (by ignoring whitespace).
|
||||
//
|
||||
//
|
||||
// In general the ezpwd::base32/64 en/decoders are designed to produce easily human-usable
|
||||
// encodings, and can ignore common whitespace characters and '-' to allow human-readable
|
||||
// formatting. The RFC4648 Standard base 32/64 and Crockford base32 encodings are also supported.
|
||||
//
|
||||
//
|
||||
// Adding new symbol encodings (and even new bases, up to base-128) is trivial.
|
||||
//
|
||||
//
|
||||
namespace ezpwd {
|
||||
|
||||
namespace serialize {
|
||||
@@ -65,20 +65,20 @@ namespace ezpwd {
|
||||
pd_enforce = 2, // Padding is expected and enforced
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
// serialize::tables -- base class for TABLES in all base<N,TABLES>
|
||||
//
|
||||
//
|
||||
// Every serialize::table<BASE> specialization must have an encoder table of size BASE,
|
||||
// and a decoder table of size 127.
|
||||
//
|
||||
//
|
||||
|
||||
//
|
||||
//
|
||||
// hex<16/32> -- RFC4648 4-bit (standard 16 symbol) and 5-bit (32 symbol)
|
||||
// standard<16/32/64> -- RFC4648 standard tables
|
||||
// standard_url<64> -- RFC4648 standard tables (base-64 URL-safe)
|
||||
// ezpwd<16/32/64> -- EZPWD tables
|
||||
// crockford<32> -- Crockford (base32 only)
|
||||
//
|
||||
//
|
||||
// These types are passed as the TABLE template parameter to base<32/64,TABLE> class
|
||||
// template instantiations. They must specify an encoder table of size BASE, and a decoder
|
||||
// table of size 127.
|
||||
@@ -90,9 +90,9 @@ namespace ezpwd {
|
||||
template < size_t N > struct ezpwd { };
|
||||
template < size_t N > struct crockford { };
|
||||
|
||||
//
|
||||
//
|
||||
// base<16> tables -- basic hexadecimal supported (hex, standard, ezpwd identical)
|
||||
//
|
||||
//
|
||||
template <> struct hex<16> {
|
||||
static const constexpr std::array<char,16>
|
||||
encoder { {
|
||||
@@ -126,9 +126,9 @@ namespace ezpwd {
|
||||
decoder = hex<16>::decoder;
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
// base<32> tables -- ezpwd, and RFC4648 hex32, crockford and standard
|
||||
//
|
||||
//
|
||||
template <> struct hex<32> {
|
||||
static const constexpr std::array<char,32>
|
||||
encoder { {
|
||||
@@ -156,7 +156,7 @@ namespace ezpwd {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7',
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7',
|
||||
} };
|
||||
static const constexpr std::array<char,127>
|
||||
decoder { {
|
||||
@@ -179,7 +179,7 @@ namespace ezpwd {
|
||||
'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P',
|
||||
'Q', 'R', 'T', 'U', 'V', 'W', 'X', 'Y',
|
||||
} };
|
||||
|
||||
|
||||
static const constexpr std::array<char,127>
|
||||
decoder { {
|
||||
nv, nv, nv, nv, nv, nv, nv, nv, nv, ws, ws, ws, ws, ws, nv, nv, // 9-13: <TAB>,<NL>,<VT>,<FF>,<CR>
|
||||
@@ -192,7 +192,7 @@ namespace ezpwd {
|
||||
23, 24, 25, 5, 26, 27, 28, 29, 30, 31, 2, nv, nv, nv, nv, // pqrstuvwxyz{|}~
|
||||
} };
|
||||
}; // struct serialize::ezpwd<32>
|
||||
|
||||
|
||||
template <> struct crockford<32> {
|
||||
static const constexpr std::array<char,32>
|
||||
encoder { {
|
||||
@@ -201,7 +201,7 @@ namespace ezpwd {
|
||||
'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q',
|
||||
'R', 'S', 'T', 'V', 'W', 'X', 'Y', 'Z',
|
||||
} };
|
||||
|
||||
|
||||
static const constexpr std::array<char,127>
|
||||
decoder { {
|
||||
nv, nv, nv, nv, nv, nv, nv, nv, nv, ws, ws, ws, ws, ws, nv, nv, // 9-13: <TAB>,<NL>,<VT>,<FF>,<CR>
|
||||
@@ -215,9 +215,9 @@ namespace ezpwd {
|
||||
} };
|
||||
}; // struct serialize::crockford<32>
|
||||
|
||||
//
|
||||
//
|
||||
// base<64> tables
|
||||
//
|
||||
//
|
||||
template <> struct uuencode<64> {
|
||||
static const constexpr std::array<char,64>
|
||||
encoder { {
|
||||
@@ -278,7 +278,7 @@ namespace ezpwd {
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '-', '_',
|
||||
'4', '5', '6', '7', '8', '9', '-', '_',
|
||||
} };
|
||||
static const constexpr std::array<char,127>
|
||||
decoder { {
|
||||
@@ -303,7 +303,7 @@ namespace ezpwd {
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '.',
|
||||
'4', '5', '6', '7', '8', '9', '+', '.',
|
||||
} };
|
||||
static const constexpr std::array<char,127>
|
||||
decoder { {
|
||||
@@ -318,14 +318,14 @@ namespace ezpwd {
|
||||
} };
|
||||
}; // struct serialize::ezpwd<64>
|
||||
|
||||
//
|
||||
//
|
||||
// base_generic<N, TABLES> -- generic base-N conversion using TABLES<N>. Doesn't have scatter/gather.
|
||||
//
|
||||
//
|
||||
// Every base-N converter requires a TABLE class of matching N, and can encode/decode.
|
||||
// in-place using the table::encoder/decoder arrays. Only specific values of N have class
|
||||
// template specialization which includes scatter/gather methods -- the generic base-N
|
||||
// template does not..
|
||||
//
|
||||
//
|
||||
template < size_t N, typename TABLES = ezpwd< N >>
|
||||
class base_generic
|
||||
: public TABLES {
|
||||
@@ -342,19 +342,19 @@ namespace ezpwd {
|
||||
return lhs;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<N>::encode(<string>) -- encode the supplied sequence of data in the domain (0,N] to base-N
|
||||
// base<N>::encode(<iter>,<iter>) -- encode the supplied std::string of (0,N] symbols in-place to base-N
|
||||
//
|
||||
//
|
||||
// Items from iterator must be convertible to a table index (ie. not -'ve, and within
|
||||
// the table size N). If the table contains 'ws' entries, they may optionally be ignored.
|
||||
// If the input symbol indexes outside the provided encoder table (or an 'nv' entry), then an
|
||||
// exception will be thrown.
|
||||
//
|
||||
//
|
||||
// If a non-zero 'pad' character is supplied, then the -1 (pd) character value will be
|
||||
// allowed (normally occurring only at the end of the input range), and a 'pad' will be
|
||||
// emitted for each one.
|
||||
//
|
||||
//
|
||||
template < typename I >
|
||||
static
|
||||
I encode(
|
||||
@@ -384,32 +384,32 @@ namespace ezpwd {
|
||||
return symbols;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<N>::decode(<iter>,<iter>) -- decode base-N symbols in-place, collapsing spaces.
|
||||
// base<N>::decode(<string>) -- decode base-N symbols in supplied std::string, collapsing spaces, in-place.
|
||||
//
|
||||
//
|
||||
// Items from iterator must be convertible to a table index (ie. not -'ve, and within
|
||||
// the table size, which is always 127).
|
||||
//
|
||||
// the table size, which is always 127).
|
||||
//
|
||||
// ws_ignored -- skip whitepace/- symbols (the default)
|
||||
// ws_invalid -- consider whitespace/- symbols as invalid symbols
|
||||
//
|
||||
//
|
||||
// pd_invalid -- consider padding symbols as invalid
|
||||
// pd_ignored -- skip padding symbols
|
||||
// pd_enforce -- leave any padding symbols in place (the default)
|
||||
//
|
||||
//
|
||||
// If erasure vector supplied, marks invalid symbols as erasures; otherwise, throws
|
||||
// exception. Ignores whitespace. Will return an iterator to just after the last output
|
||||
// symbol used in the provided range (eg. to shorten the container, if desired), leaving any
|
||||
// remaining symbols unchanged. The <string> version returns the same string reference
|
||||
// passed in (shortened, if spaces/padding ignored).
|
||||
//
|
||||
//
|
||||
// If an invalid vector is supplied, we'll also return the offending input symbol(s); if
|
||||
// an exception is raised (no erasure vector supplied), only one symbol will be in invalid.
|
||||
//
|
||||
//
|
||||
// NOTE: will quite likely return an iterator before the supplied 'end', indicating that the
|
||||
// output has been truncated (shortened), due to collapsing spaces!
|
||||
//
|
||||
//
|
||||
template < typename I >
|
||||
static
|
||||
I decode(
|
||||
@@ -509,12 +509,12 @@ namespace ezpwd {
|
||||
|
||||
//
|
||||
// gather_next -- return next symbol to gather into 8-bit output
|
||||
//
|
||||
//
|
||||
// Fails if padding mixed in with data, or a data symbol exceeds encoding bit depth
|
||||
// (eg. 5 bits for base-32).
|
||||
//
|
||||
//
|
||||
// If auto-padding, allow the caller to differentiate
|
||||
//
|
||||
//
|
||||
template < typename I >
|
||||
static
|
||||
int gather_next( I &beg, I end, pd_use_t pd_use, int previous )
|
||||
@@ -547,11 +547,11 @@ namespace ezpwd {
|
||||
}
|
||||
|
||||
namespace serialize {
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base<N> -- Arbitrary bases (other than those with specializations below)
|
||||
//
|
||||
//
|
||||
// Can en/decode, but no scatter/gather implementation, nor encode_size.
|
||||
//
|
||||
//
|
||||
template < size_t N, typename TABLES >
|
||||
class base
|
||||
: public base_generic< N, TABLES > {
|
||||
@@ -561,9 +561,9 @@ namespace ezpwd {
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base<16> -- transform individual characters between 4-bit binary and a base-16
|
||||
//
|
||||
//
|
||||
template < typename TABLES >
|
||||
class base< 16, TABLES >
|
||||
: public base_generic< 16, TABLES > {
|
||||
@@ -579,12 +579,12 @@ namespace ezpwd {
|
||||
return len * 2; // encoding base-16 always exactly doubles size
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<16>::scatter -- distribute a range of input bytes to an output iterator in 4-bit chunks
|
||||
//
|
||||
//
|
||||
// The same implementation is used for both random-access iterators, and for all
|
||||
// other forward iterators.
|
||||
//
|
||||
//
|
||||
template < typename I, typename O, typename iterator_tag >
|
||||
static
|
||||
O scatter(
|
||||
@@ -623,18 +623,18 @@ namespace ezpwd {
|
||||
return scatter( beg, end, out, pd_enforce, typename std::iterator_traits<I>::iterator_category() );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<16>::gather -- collect 4-bit chunks into 8-bit characters
|
||||
//
|
||||
//
|
||||
// If underflow occurs (not enough data collected to output complete last char), then an
|
||||
// exception will be raised. However, if 'pad' is set, then output will automatically be
|
||||
// padded, flushing out any un-emitted data remaining in previous 4-bit base-16 symbol.
|
||||
//
|
||||
//
|
||||
// For correct base-16 data produced by 'scatter', this will allow 'gather' to always
|
||||
// produce the identical output as was originally provided to 'scatter'. However, if simply
|
||||
// truncated base-16 input is provided (eg. only 1 symbols of an 2-symbol 8-bit
|
||||
// base-16 group), then the final 8-bit symbol from the original data will be missing.
|
||||
//
|
||||
//
|
||||
template < typename I, typename O >
|
||||
static
|
||||
O gather(
|
||||
@@ -663,38 +663,38 @@ namespace ezpwd {
|
||||
}
|
||||
}; // ezpwd::base<16>
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base16...
|
||||
//
|
||||
//
|
||||
// Shortcut typedefs for the available base16 codec.
|
||||
//
|
||||
//
|
||||
typedef base< 16, hex< 16 >>
|
||||
base16;
|
||||
typedef base< 16, hex< 16 >>
|
||||
base16_standard;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base<32> -- transform individual characters between 5-bit binary and a base-32
|
||||
//
|
||||
//
|
||||
// The char values [0,32) are mapped by base<32>::encode onto something like
|
||||
//
|
||||
//
|
||||
// 0123456789ABCDEFGHJKLMNPQRTUVWXY TABLES=ezpwd<32> (default)
|
||||
// 0123456789ABCDEFGHJKMNPQRSTVWXYZ TABLES=crockford<32>
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 TABLES=standard<32>
|
||||
//
|
||||
//
|
||||
// and base<32>::decode performs the inverse. In addition to folding lower-case to
|
||||
// upper-case, the following mappings occur in the ezpwd<32>::decoder table:
|
||||
//
|
||||
//
|
||||
// O -> 0
|
||||
// Z -> 2
|
||||
// S -> 5
|
||||
// I -> 1
|
||||
//
|
||||
//
|
||||
// B -> 8 could not be included due to the limited size of the capitalized alpha-numeric
|
||||
// symbol pool, unfortunately, but the other substitutions were prioritized as they are
|
||||
// more likely to occur in standard printed text.
|
||||
//
|
||||
//
|
||||
// Any characters encountered outside [0,32) by encode and outside the above set by
|
||||
// decode raise an exception, unless an erasure vector is provided, in which case we supply
|
||||
// a 0 value and store the index of the invalid symbol in the vector.
|
||||
@@ -716,12 +716,12 @@ namespace ezpwd {
|
||||
: ( len * 8 + 4 ) / 5 );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<32>::scatter -- distribute a range of input bytes to an output iterator in 5-bit chunks
|
||||
//
|
||||
//
|
||||
// Separate implementation are provided for random-access iterators (with fewer
|
||||
// comparisons necessary) and for all other forward iterators.
|
||||
//
|
||||
//
|
||||
template < typename I, typename O, typename iterator_tag >
|
||||
static
|
||||
O scatter(
|
||||
@@ -910,18 +910,18 @@ namespace ezpwd {
|
||||
return scatter( beg, end, out, pd_enforce, typename std::iterator_traits<I>::iterator_category() );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<32>::gather -- collect 5-bit chunks into 8-bit characters
|
||||
//
|
||||
//
|
||||
// If underflow occurs (not enough data collected to output complete last char), then an
|
||||
// exception will be raised. However, if 'pad' is set, then output will automatically be
|
||||
// padded, discarding any un-emitted data remaining in previous 5-bit base-32 symbols.
|
||||
//
|
||||
//
|
||||
// For correct base-32 data produced by 'scatter', this will allow 'gather' to always
|
||||
// produce the identical output as was originally provided to 'scatter'. However, if simply
|
||||
// truncated base-32 input is provided (eg. only 1, 3 or 5 symbols of an 8-symbol 40-bit
|
||||
// base-32 group), then the final 8-bit symbol from the original data will be missing.
|
||||
//
|
||||
//
|
||||
template < typename I, typename O >
|
||||
static
|
||||
O gather(
|
||||
@@ -939,7 +939,7 @@ namespace ezpwd {
|
||||
int c2 = gather_next( beg, end, pd_use, c1 );
|
||||
int c3 = gather_next( beg, end, pd_use, c2 );
|
||||
if ( c1 >= 0 and c2 >= 0 and c3 >= 0 )
|
||||
*out++ = ( ((c1 < 0 ? 0 : c1) & 0x03) << 6
|
||||
*out++ = ( ((c1 < 0 ? 0 : c1) & 0x03) << 6
|
||||
| (c2 < 0 ? 0 : c2) << 1
|
||||
| (c3 < 0 ? 0 : c3) >> 4 );
|
||||
int c4 = gather_next( beg, end, pd_use, c3 );
|
||||
@@ -949,12 +949,12 @@ namespace ezpwd {
|
||||
int c5 = gather_next( beg, end, pd_use, c4 );
|
||||
int c6 = gather_next( beg, end, pd_use, c5 );
|
||||
if ( c4 >=0 and c5 >= 0 and c6 >= 0 )
|
||||
*out++ = ( ((c4 < 0 ? 0 : c4) & 0x01) << 7
|
||||
*out++ = ( ((c4 < 0 ? 0 : c4) & 0x01) << 7
|
||||
| (c5 < 0 ? 0 : c5) << 2
|
||||
| (c6 < 0 ? 0 : c6) >> 3 );
|
||||
int c7 = gather_next( beg, end, pd_use, c6 );
|
||||
if ( c6 >= 0 and c7 >= 0 )
|
||||
*out++ = ( ((c6 < 0 ? 0 : c6 ) & 0x07) << 5
|
||||
*out++ = ( ((c6 < 0 ? 0 : c6 ) & 0x07) << 5
|
||||
| (c7 < 0 ? 0 : c7 ));
|
||||
}
|
||||
return out;
|
||||
@@ -970,11 +970,11 @@ namespace ezpwd {
|
||||
}
|
||||
}; // ezpwd::base<32>
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base32...
|
||||
//
|
||||
//
|
||||
// Shortcut typedefs for the available base32 codecs.
|
||||
//
|
||||
//
|
||||
typedef base< 32, ezpwd< 32 >>
|
||||
base32;
|
||||
typedef base< 32, hex< 32 >>
|
||||
@@ -985,21 +985,21 @@ namespace ezpwd {
|
||||
base32_crockford;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base<64> -- transform individual characters between 6-bit binary and base-64
|
||||
//
|
||||
//
|
||||
// The char values [0,64) are mapped by base64::encode onto either the
|
||||
// standard or ezpwd (url-safe) tables:
|
||||
//
|
||||
//
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ -- RFC4648 standard
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_ -- RFC4648 standard_url
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+. -- ezpwd
|
||||
//
|
||||
//
|
||||
// and base<64>::decode performs the inverse (handles both standard and url-safe encodings).
|
||||
//
|
||||
//
|
||||
// Any characters encountered outside [0,64) by encode and outside the above set
|
||||
// by decode raise an exception.
|
||||
//
|
||||
//
|
||||
template < typename TABLES >
|
||||
class base< 64, TABLES >
|
||||
: public base_generic< 64, TABLES > {
|
||||
@@ -1017,9 +1017,9 @@ namespace ezpwd {
|
||||
: ( len * 4 + 2 ) / 3 );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<64>::scatter -- distribute a range of input bytes to an output iterator in 6-bit chunks
|
||||
//
|
||||
//
|
||||
template < typename I, typename O, typename iterator_tag >
|
||||
static
|
||||
O scatter(
|
||||
@@ -1129,9 +1129,9 @@ namespace ezpwd {
|
||||
return scatter( beg, end, out, pd_enforce, typename std::iterator_traits<I>::iterator_category() );
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// base<64>::gather -- collect 6-bit chunks into 8-bit characters
|
||||
//
|
||||
//
|
||||
template < typename I, typename O >
|
||||
static
|
||||
O gather(
|
||||
@@ -1148,7 +1148,7 @@ namespace ezpwd {
|
||||
| (c1 < 0 ? 0 : c1 ) >> 4 );
|
||||
int c2 = gather_next( beg, end, pd_use, c1 );
|
||||
if ( c1 >= 0 and c2 >= 0 )
|
||||
*out++ = ( ((c1 < 0 ? 0 : c1) & 0x0f) << 4
|
||||
*out++ = ( ((c1 < 0 ? 0 : c1) & 0x0f) << 4
|
||||
| (c2 < 0 ? 0 : c2) >> 2 );
|
||||
int c3 = gather_next( beg, end, pd_use, c2 );
|
||||
if ( c2 >= 0 and c3 >= 0 )
|
||||
@@ -1168,11 +1168,11 @@ namespace ezpwd {
|
||||
}
|
||||
}; // ezpwd::serialize::base<64>
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::serialize::base64...
|
||||
//
|
||||
//
|
||||
// Shortcut typedefs for the standard base-64 codecs.
|
||||
//
|
||||
//
|
||||
typedef base< 64, ezpwd< 64 >>
|
||||
base64;
|
||||
typedef base< 64, standard< 64 >>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
|
||||
//
|
||||
//
|
||||
// The encoder/decoder tables for all ezpwd::serialize::... base<N> codecs
|
||||
//
|
||||
//
|
||||
// Must be included in exactly one C++ compilation unit.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef _EZPWD_SERIALIZE_DEFINITIONS
|
||||
#define _EZPWD_SERIALIZE_DEFINITIONS
|
||||
|
||||
#include "serialize"
|
||||
|
||||
//
|
||||
//
|
||||
// base<16> tables for RFC4864 standard
|
||||
//
|
||||
//
|
||||
const constexpr std::array<char,16>
|
||||
ezpwd::serialize::hex<16>::encoder;
|
||||
const constexpr std::array<char,127>
|
||||
ezpwd::serialize::hex<16>::decoder;
|
||||
|
||||
//
|
||||
//
|
||||
// base<32> tables for RFC4864 standard, and the Hex32, EZPWD and Crockford codecs
|
||||
//
|
||||
//
|
||||
const constexpr std::array<char,32>
|
||||
ezpwd::serialize::hex<32>::encoder;
|
||||
const constexpr std::array<char,127>
|
||||
@@ -38,9 +38,9 @@ const constexpr std::array<char,32>
|
||||
const constexpr std::array<char,127>
|
||||
ezpwd::serialize::crockford<32>::decoder;
|
||||
|
||||
//
|
||||
//
|
||||
// base<64> tables for RFC4864 standard (regular and url), and the EZPWD codecs
|
||||
//
|
||||
//
|
||||
const constexpr std::array<char,64>
|
||||
ezpwd::serialize::standard<64>::encoder;
|
||||
const constexpr std::array<char,127>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
//
|
||||
//
|
||||
// ezpwd::timeofday -- Return current time.
|
||||
// ezpwd::epoch -- The UNIX epoch.
|
||||
// ezpwd::seconds -- convert timeval to a real-valued seconds
|
||||
|
||||
Reference in New Issue
Block a user