forked from Novators/libsqrl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSqrlEncoder.cpp
More file actions
110 lines (97 loc) · 2.45 KB
/
SqrlEncoder.cpp
File metadata and controls
110 lines (97 loc) · 2.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "sqrl_internal.h"
#include "SqrlEncoder.h"
#include "SqrlString.h"
#include "SqrlBigInt.h"
namespace libsqrl
{
SqrlEncoder::SqrlEncoder() : SqrlEncoder( "0123456789abcdef" ) {}
SqrlEncoder::SqrlEncoder( const char * alphabet ) {
this->alphabet = alphabet;
this->reverseMath = true;
}
SqrlString *SqrlEncoder::encode( SqrlString *dest, const SqrlString *src, bool append ) {
if( !src ) return NULL;
if( !dest ) {
dest = new SqrlString();
}
if( !append ) {
dest->clear();
}
if( src->length() == 0 ) return dest;
int base = (int)strlen( this->alphabet );
double cpb = 8.0 / log2(base);
int zc = 0;
SqrlBigInt s( src );
SqrlString ob( (size_t)ceil( src->length() * cpb ) );
const uint8_t *it = s.cdata();
const uint8_t *end = s.cdend();
while( it[0] == 0 && it != end ) {
zc++;
it++;
}
zc *= (int)ceil(cpb);
if( this->reverseMath ) s.reverse();
do {
ob.push_back( this->alphabet[(s.divideBy(base)) % base] );
} while( s.length() );
ob.append( this->alphabet[0], zc );
if( this->reverseMath ) ob.reverse();
dest->append( &ob );
return dest;
}
SqrlString *SqrlEncoder::decode( SqrlString *dest, const SqrlString *src, bool append ) {
if( !src ) return NULL;
if( !dest ) {
dest = new SqrlString();
}
if( !append ) {
dest->clear();
}
if( src->length() == 0 ) return dest;
int base = (int)strlen( this->alphabet );
SqrlString s = SqrlString( src );
if( !this->reverseMath ) s.reverse();
SqrlBigInt num = SqrlBigInt();
const char *ch;
uint8_t dp;
size_t leadingZeros = 0;
size_t cpb = (size_t)ceil( 8.0 / log2(base) );
const uint8_t *it = s.cdata();
const uint8_t *end = s.cdend();
while( it[0] == this->alphabet[0] && it != end ) {
leadingZeros++;
it++;
}
leadingZeros = leadingZeros / cpb;
while( it != end ) {
ch = strchr( this->alphabet, *it );
if( ch ) {
dp = (uint8_t)(ch - this->alphabet);
num.multiplyBy( base );
num.add( dp );
}
it++;
}
if( !this->reverseMath ) num.reverse();
if( leadingZeros ) {
dest->append( (char)0, leadingZeros );
}
dest->append( &num );
return dest;
}
bool SqrlEncoder::validate( const SqrlString *src, size_t *error ) {
if( !src ) return false;
const char *it = src->cstring();
const char *end = src->cstrend();
while( it != end ) {
if( !strchr( this->alphabet, *it ) ) {
if( error ) {
*error = it - src->cstring();
}
return false;
}
it++;
}
return true;
}
}