CODE: Remove Whitespace (ezpwd);

This commit is contained in:
lwvmobile
2025-03-17 17:22:22 -04:00
parent fdbc2ef0e2
commit 4e77bb05b9
13 changed files with 345 additions and 346 deletions

View File

@@ -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() )
{

View File

@@ -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<<(

View File

@@ -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,

View File

@@ -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;
};

View File

@@ -1,6 +1,6 @@
//
//
// C++ Definitions -- include once in a single C++ compilation unit
//
//
#ifndef _EZPWD_DEFINITIONS
#define _EZPWD_DEFINITIONS

View File

@@ -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;

View File

@@ -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<<(

View File

@@ -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

View File

@@ -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

View File

@@ -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 >>

View File

@@ -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>

View File

@@ -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