mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 08:47:24 -05:00
CODE: Remove Whitespace (ezpwd);
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
|
||||
# Digital Speech Decoder - Florida Man Edition
|
||||
|
||||
DSD-FME is an evolution of the original DSD project from 'DSD Author' using the base code of [szechyjs](https://github.com/szechyjs/dsd "szechyjs"), some code and ideas from [LouisErigHerve](https://github.com/LouisErigHerve/dsd "LouisErigHerve"), [Boatbod OP25](https://github.com/boatbod/op25 "Boatbod OP25") and
|
||||
[Osmocom OP25](https://gitea.osmocom.org/op25/op25 "Osmocom OP25"), along with other snippets of code, information, and inspirations from other projects including [DSDcc](https://github.com/f4exb/dsdcc "DSDcc"), [SDRTRunk](https://github.com/DSheirer/sdrtrunk "SDRTrunk"), [MMDVMHost](https://github.com/g4klx/MMDVMHost "MMDVMHost"), [LFSR](https://github.com/mattames/LFSR "LFSR"), [OK-DMRlib](https://github.com/OK-DMR/ok-dmrlib "OK-DMRlib"), and [EZPWD-Reed-Solomon](https://github.com/pjkundert/ezpwd-reed-solomon "EZPWD"), Eric Cottrell, SP5WWP and others. Finally, this is all brought together with original code to extend the fuctionality and add new features including NCurses Terminal and Menu system, Pulse Audio, TCP Direct Link Audio, RIGCTL, Trunking Features, LRRP/GPS Mapping, P25 Phase 2, EDACS, YSF, M17, OP25 Capture Bin compatability, etc. DSD-FME is primarily focused with Linux Desktop users in mind, so please understand that this version may not compile, compile easily, or run correctly in other environments.
|
||||
DSD-FME is an evolution of the original DSD project from 'DSD Author' using the base code of [szechyjs](https://github.com/szechyjs/dsd "szechyjs"), some code and ideas from [LouisErigHerve](https://github.com/LouisErigHerve/dsd "LouisErigHerve"), [Boatbod OP25](https://github.com/boatbod/op25 "Boatbod OP25") and [Osmocom OP25](https://gitea.osmocom.org/op25/op25 "Osmocom OP25"), along with other snippets of code, information, and inspirations from other projects including [DSDcc](https://github.com/f4exb/dsdcc "DSDcc"), [SDRTRunk](https://github.com/DSheirer/sdrtrunk "SDRTrunk"), [MMDVMHost](https://github.com/g4klx/MMDVMHost "MMDVMHost"), [LFSR](https://github.com/mattames/LFSR "LFSR"), [OK-DMRlib](https://github.com/OK-DMR/ok-dmrlib "OK-DMRlib"), and [EZPWD-Reed-Solomon](https://github.com/pjkundert/ezpwd-reed-solomon "EZPWD"), Eric Cottrell, SP5WWP and others. Finally, this is all brought together with original code to extend the fuctionality and add new features including NCurses Terminal and Menu system, Pulse Audio, TCP Direct Link Audio, RIGCTL, Trunking Features, LRRP/GPS Mapping, P25 Phase 2, EDACS, YSF, M17, OP25 Capture Bin compatability, etc. DSD-FME is primarily focused with Linux Desktop users in mind, so please understand that this version may not compile, compile easily, or run correctly in other environments.
|
||||
|
||||
This project wouldn't be possible without a few good people providing me plenty of sample audio files to run over and over again. Special thanks to jurek1111, KrisMar, noamlivne, racingfan360, iScottyBotty, LimaZulu, Forts, thewraithe2008, RayAir, Cretu, ilyacodes, and others for the many hours of wav samples and information provided by them. Most importantly, HRH17, whose insight, information, samples, and willingness to let me remote into a computer half-way across the globe in order to test trunking features are what make DSD-FME what it has become. I'd also like to thank mrscanner2008 for providing an additional remote where additional NXDN Type-C, 'Idas' Type-D, and XPT decoding and trunking could be sorted out. Thanks to volo-zyko for cleaning up a lot of code. Thank you everybody.
|
||||
|
||||
|
||||
@@ -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