Fixed "System::OpenURI". Added SHA256. Added URI safe Base64 methods.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 6m9s
Build & Release / Linux-AMD64-Build (push) Successful in 15m26s
Build & Release / Linux-AARCH64-Build (push) Successful in 45m54s

This commit is contained in:
2025-05-11 19:43:50 -07:00
parent 2cb01a7c65
commit bce48fe121
12 changed files with 491 additions and 58 deletions

View File

@@ -2,8 +2,36 @@
namespace ehs
{
const char Base64::ascii[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Str_8 Base64::EncodeURL(const Str_8 &input)
{
UInt_64 input_length = input.Size();
// Calculate the output length
UInt_64 output_length = (input_length * 4 + 2) / 3;
// Allocate memory for the output
Str_8 result(output_length);
// Loop through the input and fill the output
for (int i = 0, j = 0; i < input_length;) {
// Take first byte and shift right by 2 bits
UInt_32 octet_a = (UInt_8)input[i++];
UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_c = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 triple = (octet_a << 16) + (octet_b << 8) + octet_c;
// Encode the 24-bits into four 6-bits integers
result[j++] = asciiUrl[(triple >> 3 * 6) & 0x3F];
result[j++] = asciiUrl[(triple >> 2 * 6) & 0x3F];
result[j++] = asciiUrl[(triple >> 1 * 6) & 0x3F];
result[j++] = asciiUrl[(triple >> 0 * 6) & 0x3F];
}
return result;
}
Str_8 Base64::Encode(const Str_8 &input)
{
UInt_64 input_length = input.Size();
@@ -18,9 +46,9 @@ namespace ehs
for (int i = 0, j = 0; i < input_length;) {
// Take first byte and shift right by 2 bits
UInt_32 octet_a = i < input_length ? input[i++] : 0;
UInt_32 octet_b = i < input_length ? input[i++] : 0;
UInt_32 octet_c = i < input_length ? input[i++] : 0;
UInt_32 octet_a = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_b = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 octet_c = i < input_length ? (UInt_8)input[i++] : 0;
UInt_32 triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
@@ -41,64 +69,152 @@ namespace ehs
return result;
}
Str_8 Base64::Decode(const Str_8 &input)
Str_8 Base64::DecodeURL(const Str_8 &input)
{
UInt_64 in_len = input.Size();
int i = 0;
int j = 0;
int in_ = 0;
char char_array_4[4], char_array_3[3];
Str_8 ret;
Str_8 result(input.Size() * 3 / 4);
while (in_len-- && ( input[in_] != '=') && IsBase64(input[in_]))
UInt_64 remaining = input.Size();
UInt_64 offsetIn = 0;
UInt_64 offsetOut = 0;
UInt_8 quartet[4];
while (remaining)
{
char_array_4[i++] = input[in_]; in_++;
if (i ==4)
if (remaining >= 4)
{
for (i = 0; i <4; i++)
char_array_4[i] = Find(char_array_4[i]);
for (UInt_8 i = 0; i < 4; ++i)
{
if (!IsBase64URL(input[offsetIn + i]))
return {};
char_array_3[0] = ( char_array_4[0] << 2 ) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
quartet[i] = FindURL(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[1] << 4) | (((UInt_8*)&quartet)[2] >> 2));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[2] << 6) | ((UInt_8*)&quartet)[3]);
i = 0;
offsetIn += 4;
remaining -= 4;
}
else
{
for (UInt_8 i = 0; i < 4; ++i)
{
if (i < remaining)
{
if (!IsBase64URL(input[offsetIn + i]))
return {};
quartet[i] = FindURL(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
else
quartet[i] = 0;
}
result[offsetOut++] = (Char_8)((quartet[0] << 2) | (quartet[1] >> 4));
if (remaining == 3)
result[offsetOut++] = (Char_8)((quartet[1] << 4) | (quartet[2] >> 2));
offsetIn += remaining;
remaining = 0;
}
}
if (i)
return result;
}
Str_8 Base64::Decode(const Str_8 &input)
{
Str_8 result(input.Size() * 3 / 4);
UInt_64 remaining = input.Size();
UInt_64 offsetIn = 0;
UInt_64 offsetOut = 0;
UInt_8 quartet[4];
while (remaining)
{
for (j = 0; j < i; j++)
char_array_4[j] = Find(char_array_4[j]);
if (remaining >= 4)
{
for (UInt_8 i = 0; i < 4; ++i)
{
if (!IsBase64(input[offsetIn + i]))
return {};
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
quartet[i] = Find(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
for (j = 0; (j < i - 1); j++)
ret += char_array_3[j];
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[0] << 2) | (((UInt_8*)&quartet)[1] >> 4));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[1] << 4) | (((UInt_8*)&quartet)[2] >> 2));
result[offsetOut++] = (Char_8)((((UInt_8*)&quartet)[2] << 6) | ((UInt_8*)&quartet)[3]);
offsetIn += 4;
remaining -= 4;
}
else
{
for (UInt_8 i = 0; i < 4; ++i)
{
if (i < remaining)
{
if (!IsBase64(input[offsetIn + i]))
return {};
quartet[i] = Find(input[offsetIn + i]);
if (quartet[i] == EHS_UINT_8_MAX)
return {};
}
else
quartet[i] = 0;
}
result[offsetOut++] = (Char_8)((quartet[0] << 2) | (quartet[1] >> 4));
if (remaining == 3)
result[offsetOut++] = (Char_8)((quartet[1] << 4) | (quartet[2] >> 2));
offsetIn += remaining;
remaining = 0;
}
}
return ret;
return result;
}
char Base64::Find(const char c)
UInt_8 Base64::FindURL(const UInt_8 &c)
{
for (char i = 0; i < (char)sizeof(ascii); ++i)
{
for (UInt_8 i = 0; i < (UInt_8)sizeof(asciiUrl) - 1; ++i)
if (asciiUrl[i] == c)
return i;
return EHS_UINT_8_MAX;;
}
UInt_8 Base64::Find(const UInt_8 &c)
{
for (UInt_8 i = 0; i < (UInt_8)sizeof(ascii) - 1; ++i)
if (ascii[i] == c)
return i;
}
return EHS_SINT_8_MAX;
}
bool Base64::IsBase64(const char c)
bool Base64::IsBase64URL(const UInt_8 &c)
{
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || (c == '+') || (c == '/');
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || c == '-' || c == '_';
}
bool Base64::IsBase64(const UInt_8 &c)
{
return (c > 47 && c < 58) || (c > 64 && c < 91) || (c > 96 && c < 123) || c == '+' || c == '/';
}
}