Skip to content

Commit

Permalink
Update SCoreNumber.baseConvert_v1.fmfn
Browse files Browse the repository at this point in the history
  • Loading branch information
nilswald committed Aug 11, 2022
1 parent 15c3324 commit 8b8aebe
Showing 1 changed file with 30 additions and 15 deletions.
45 changes: 30 additions & 15 deletions functions/SCoreNumber/baseConvert/SCoreNumber.baseConvert_v1.fmfn
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
/* SCoreNumber.baseConvert( _value; _from; _to )
/* F1SCoreNumber.baseConvert( _value; _from; _to )
@about coverts between different bases, e.g. base10 (decimal) to base2 (binary)
@author Nils Waldherr <[email protected]>
@copyright ©2020 FMGARAGE
@license https://opensource.org/licenses/mit MIT
@version 1.0.0-101 - 12.06.2021 – NW:
@version 1.0.0-104 - 12.06.2021 – NW
1.1.0-105 - 25.02.2022 - NW: base32hex
@package f1.system.core.number
@link https://github.com/fmgarage/ft-functions/tree/main/functions/SCoreNumber/baseConvert
@doc https://fmgarage.github.io/ft-functions/SCoreNumber/baseConvert.html
@param string _value
int _from -- 2..
2 binary
10 decimal
16 hex
32 base32
32,16 base32hex
64 base64
84 encodes utf8 with internal code() function
85 base85
all other values use the [9-9][a-z] pool (max 36)
all other values use the [0-9][a-z] pool (max 36)
int _to
84 decodes to utf8 with internal char() function


@return string|int value | string "ERROR: ..."
@info https://cryptii.com

*/
Case(
Expand Down Expand Up @@ -51,7 +52,7 @@ Case(
IsEmpty( _to ); "ERROR: parameter _to must not be empty";

// _to < 2, > 36
_to+0 < 2 or ( _to+0 > 36 and _to+0 ≠ 64 and _to+0 ≠ 84 and _to+0 ≠ 85 );
_to+0 < 2 or ( _to+0 > 36 and _to+0 ≠ 64 and _to+0 ≠ 84 and _to+0 ≠ 85 and _to );
"ERROR: parameter _to = " & _to & " could not be resolved";

// no conversion
Expand All @@ -63,6 +64,9 @@ Case(
----------------------------------------------------------------------------------
*/
Let(
/* step 1: convert to decimal
----------------------------------------
*/
[
_from = _from+0;
_to = _to+0;
Expand All @@ -77,20 +81,25 @@ Case(
// else convert
While(
[
// floor _from
from = Int( _from );

// set the right pool for input base
pool = Case(
_from = 32; "abcdefghijklmnopqrstuvwxyz234567";
_from = 32,16; "0123456789ABCDEFGHIJKLMNOPQRSTUV";
_from = 64; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
_from = 85; "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
Left( "0123456789abcdefghijklmnopqrstuvwxyz"; _from )
Left( "0123456789abcdefghijklmnopqrstuvwxyz"; from )
);
l = Length( _value );
decimal = 0;
error = "";
pos = 1;
i = 0
];
// i++ until length, exit on error
i < l and IsEmpty( error );
i < l and IsEmpty( error ) and pos > 0;
[
// get digit from input - rtl
digit = Middle( _value; l-i; 1 );
Expand All @@ -106,24 +115,27 @@ Case(
);

// add value to the result
decimal = decimal + ((pos-1) * Max( 1; _from ^ i ));
decimal = decimal + ((pos-1) * Max( 1; from ^ i ));
i = i+1
];
// return
Case(
// if digit not in pool return error
pos = 0; "ERROR: digit '" & digit & "' not in pool";
pos = 0; "ERROR: digit '" & digit & "' could not be resolved";

// resulting value
decimal
)
)
)
];


// generate target format
/* step 2: convert to target format
----------------------------------------
*/
Case(
// error
// check for error
Left( decimal; 5 ) = "ERROR";
decimal;

Expand All @@ -142,19 +154,22 @@ Case(
// copy decimal into the scope
decimal = decimal;

// floor _to
to = Int( _to );

// set pool for output base
pool = Case(
_to = 32; "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
_to = 64; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
_to = 85; "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
Left( "0123456789abcdefghijklmnopqrstuvwxyz"; _to )
Left( "0123456789abcdefghijklmnopqrstuvwxyz"; to )
)
];
// iterate as long as decimal has a value, at least once
decimal > 0 or IsEmpty( result );
[
// set value for the current digit - rtl
rest = Mod( decimal; _to );
rest = Mod( decimal; to );

// get the according digit from pool
digit = Middle( pool; rest+1; 1 );
Expand All @@ -163,7 +178,7 @@ Case(
result = digit & result;

// transfer to next digit
decimal = Int( decimal / _to )
decimal = Int( decimal / to )
];
// return resulting string
result
Expand Down

0 comments on commit 8b8aebe

Please sign in to comment.