-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b6c83f3
Showing
8 changed files
with
426 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Copyright 2024 ICDevs.org - forked from Deland-Labs | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"version": 1, | ||
"canisters": { | ||
"test": { | ||
"type": "motoko", | ||
"main": "tests/ActorTest.mo", | ||
"args": "-v --compacting-gc" | ||
} | ||
}, | ||
"defaults": { | ||
"build": { | ||
"packtool": "mops sources", | ||
"args": "" | ||
}, | ||
"replica": { | ||
"subnet_type": "system" | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[dependencies] | ||
base = "0.11.1" | ||
|
||
[dev-dependencies] | ||
test = "1.2.0" | ||
fuzz = "0.2.1" | ||
|
||
[package] | ||
name = "principal-ext" | ||
version = "0.1.0" | ||
description = "Extensions for Principal" | ||
repository = "https://github.com/icdevsorg/principal-ext.mo" | ||
keywords = [ "prinicipal"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
This library has been forked from https://github.com/Deland-Labs/fungible-token-standard/blob/06ad30ea8a8c27b6eaada9c214f39e8f50eb8d4b/canisters/dft_motoko/utils/PrincipalExt.mo in order to get it into mops. Please contact [email protected] if you are Deland-Labs would like take over ownership in mops. | ||
|
||
# Principal Utilities Module | ||
|
||
This project provides a module to work with Internet Computer (IC) Principals, including functions to decode and validate Principal strings, and determine the type of a Principal (canister or user). | ||
|
||
## Overview | ||
|
||
The module provides the following functionalities: | ||
- `fromText`: Decodes a Principal from its textual representation and validates it. Returns null if it fails | ||
- `isCanister`: Checks if a given Principal is a canister ID. | ||
- `isUserPrincipal`: Checks if a given Principal is a user ID. | ||
|
||
## Installation | ||
|
||
```sh | ||
mops add principal-ext | ||
``` | ||
|
||
## Usage | ||
|
||
### fromText | ||
|
||
```motoko | ||
let principal: ?Principal = PrincipalModule.fromText("aaaaa-aa"); | ||
``` | ||
|
||
The `fromText` function decodes a Principal from its textual representation and validates it. It returns an optional Principal (`?Principal`). | ||
|
||
### isCanister | ||
|
||
```motoko | ||
let isCanister: Bool = PrincipalModule.isCanister(principal); | ||
``` | ||
|
||
The `isCanister` function checks if a given Principal is a canister ID. It returns a boolean (`Bool`). | ||
|
||
### isUserPrincipal | ||
|
||
```motoko | ||
let isUser: Bool = PrincipalModule.isUserPrincipal(principal); | ||
``` | ||
|
||
The `isUserPrincipal` function checks if a given Principal is a user ID. It returns a boolean (`Bool`). | ||
|
||
## License | ||
|
||
This project is licensed under the Apache 2.0 license. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
/// https://github.com/flyq/ic_codec/blob/8a6f2fff88758125fd7e3ce54f99366f9c121eda/src/base32.mo | ||
/// This library lets you encode and decode in either RFC4648 Base32 or in Crockford Base32. | ||
|
||
import Array "mo:base/Array"; | ||
import Iter "mo:base/Iter"; | ||
import Text "mo:base/Text"; | ||
import Char "mo:base/Char"; | ||
import Nat8 "mo:base/Nat8"; | ||
import Int8 "mo:base/Int8"; | ||
import Nat "mo:base/Nat"; | ||
import Nat32 "mo:base/Nat32"; | ||
import Int "mo:base/Int"; | ||
|
||
// refers: https://docs.rs/crate/base32/0.4.0/source/src/lib.rs | ||
module { | ||
let RFC4648_ALPHABET: [Nat8]= [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, 50, 51, 52, 53, 54, 55]; // b"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" | ||
let CROCKFORD_ALPHABET: [Nat8] = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 77, 78, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90]; // b"0123456789ABCDEFGHJKMNPQRSTVWXYZ" | ||
let RFC4648_INV_ALPHABET: [Int8] = [-1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 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]; | ||
let CROCKFORD_INV_ALPHABET: [Int8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31]; | ||
|
||
/// RFC4648 Base32 or Crockford Base32 | ||
public type Alphabet = { | ||
#RFC4648: { padding: Bool; }; | ||
#Crockford; | ||
}; | ||
|
||
/// encode the bytes | ||
public func encode(alphabet: Alphabet, data: [Nat8]) : Text { | ||
let (alpha, padding) = switch alphabet { | ||
case (#RFC4648 { padding }) { (RFC4648_ALPHABET, padding); }; | ||
case (#Crockford) { (CROCKFORD_ALPHABET, false); }; | ||
}; | ||
let len =(data.size() + 3)/4*5; | ||
var ret: [var Nat8] = [var]; | ||
var res: Text = ""; | ||
let chunks = bytesToChunks(data, 5); | ||
for (i in chunks.keys()) { | ||
let buf: [var Nat8] = Array.init<Nat8>(5, 0); | ||
for (j in chunks[i].keys()) { | ||
buf[j] := chunks[i][j]; | ||
}; | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat((buf[0] & 0xF8) >> 3)]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat(((buf[0] & 0x07) << 2) | ((buf[1] & 0xC0) >> 6))]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat((buf[1] & 0x3E) >> 1)]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat(((buf[1] & 0x01) << 4) | ((buf[2] & 0xF0) >> 4))]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat(((buf[2] & 0x0F) << 1) | (buf[3] >> 7))]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat((buf[3] & 0x7C) >> 2)]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat(((buf[3] & 0x03) << 3) | ((buf[4] & 0xE0) >> 5))]])); | ||
ret := Array.thaw(Array.append(Array.freeze(ret), [alpha[Nat8.toNat(buf[4] & 0x1F)]])); | ||
}; | ||
var len_ret: Nat = ret.size(); | ||
if ((data.size() % 5) != 0) { | ||
let len = ret.size(); | ||
var num_extra = 0; | ||
if (8 < ((data.size() % 5 * 8 + 4) / 5)) { | ||
num_extra := 0; | ||
} else { | ||
num_extra := 8 - ((data.size() % 5 * 8 + 4) / 5); | ||
}; | ||
if padding { | ||
for (i in Iter.range(1, num_extra)) { | ||
ret[len - i] := 61; // b'=' == 61 | ||
}; | ||
} else { | ||
len_ret := len - num_extra; | ||
}; | ||
}; | ||
for (i in Iter.range(0, len_ret-1)) { | ||
res := res # Char.toText(Char.fromNat32(Nat32.fromNat(Nat8.toNat(ret[i]) ))); | ||
}; | ||
return res; | ||
}; | ||
|
||
/// decode the text | ||
public func decode(alphabet: Alphabet, data: Text) : ?[Nat8] { | ||
if (not is_ascii(data)) { | ||
return null; | ||
}; | ||
var bytes: [Nat8] = []; | ||
for (i in Text.toIter(data)) { | ||
bytes := Array.append(bytes, [Nat8.fromNat(Nat32.toNat(Char.toNat32(i)))]); | ||
}; | ||
let alpha = switch (alphabet) { | ||
case (#RFC4648 { padding }) { RFC4648_INV_ALPHABET; }; | ||
case (#Crockford) { CROCKFORD_INV_ALPHABET; }; | ||
}; | ||
var unpadded_bytes_length = bytes.size(); | ||
label l for (i in Iter.range(1, Nat.min(6, bytes.size()))) { | ||
if (bytes[bytes.size() - i] != 61) { // b'=' == 61 | ||
break l; | ||
}; | ||
unpadded_bytes_length -= 1; | ||
}; | ||
let output_length = unpadded_bytes_length*5/8; | ||
var ret: [Nat8] = []; | ||
let ret_len = (output_length+4)/5*5; | ||
let chunks = bytesToChunks(bytes, 8); | ||
for (i in chunks.keys()) { | ||
let buf: [var Nat8] = Array.init<Nat8>(8, 0); | ||
for (j in chunks[i].keys()) { | ||
switch (get_element(alpha, Nat8.toNat(wrapping_sub(to_ascii_uppercase(chunks[i][j]), 48)) )) { // b'0' == 48 | ||
case (?-1 or null) { return null; }; | ||
case (?val) { buf[j] := Int8.toNat8(val); }; | ||
} | ||
}; | ||
ret := Array.append(ret, [((buf[0] << 3) | (buf[1] >> 2))]); | ||
ret := Array.append(ret, [((buf[1] << 6) | (buf[2] << 1) | (buf[3] >> 4))]); | ||
ret := Array.append(ret, [((buf[3] << 4) | (buf[4] >> 1))]); | ||
ret := Array.append(ret, [((buf[4] << 7) | (buf[5] << 2)) | (buf[6] >> 3)]); | ||
ret := Array.append(ret, [((buf[6] << 5) | buf[7])]); | ||
}; | ||
var res = Array.init<Nat8>(output_length, 0); | ||
for (i in res.keys()) { | ||
res[i] := ret[i]; | ||
}; | ||
return ?Array.freeze(res); | ||
}; | ||
|
||
func bytesToChunks(bytes: [Nat8], interval: Nat) : [[Nat8]] { | ||
let len = bytes.size(); | ||
var ret: [[Nat8]] = []; | ||
for (i in Iter.range(1, len)) { | ||
var chunk: [var Nat8] = Array.init<Nat8>(interval, 0); | ||
if (i % interval == 0) { | ||
for (j in Iter.range(0, interval-1)) { | ||
chunk[j] := bytes[i-(interval-j)]; | ||
}; | ||
ret := Array.append(ret, [Array.freeze(chunk)]); | ||
}; | ||
}; | ||
if (len % interval != 0) { | ||
var chunk: [Nat8] = []; | ||
for (i in Iter.range(0, (len % interval) - 1)) { | ||
chunk := Array.append<Nat8>(chunk, [bytes[len - (len % interval) + i]]); | ||
}; | ||
ret := Array.append<[Nat8]>(ret, [chunk]); | ||
}; | ||
return ret; | ||
}; | ||
|
||
func is_ascii(a: Text) : Bool { | ||
for (i in Text.toIter(a)) { | ||
if (Char.toNat32(i) > 0x7F) { | ||
return false; | ||
}; | ||
}; | ||
return true; | ||
}; | ||
|
||
func to_ascii_uppercase(a: Nat8) : Nat8 { | ||
if (is_ascii_lowercase(Char.fromNat32(Nat32.fromNat(Nat8.toNat(a))))) { | ||
return 32 ^ a; | ||
} else { | ||
return a; | ||
}; | ||
}; | ||
|
||
func is_ascii_lowercase(a: Char) : Bool { | ||
return (a >= 'a' and a <= 'z'); | ||
}; | ||
|
||
func get_element(a: [Int8], index: Nat) : ?Int8 { | ||
if (index < a.size()) { | ||
return ?a[index]; | ||
} else { | ||
return null; | ||
}; | ||
}; | ||
|
||
func wrapping_sub(a: Nat8, b: Nat8) : Nat8 { | ||
if (a < b) { | ||
return 255 - b + a + 1; | ||
} else { | ||
return a - b; | ||
}; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
CRC32.mo based on: https://github.com/enzoh/motoko-crc/blob/master/src/CRC8.mo | ||
*/ | ||
|
||
import Prim "mo:prim"; | ||
import Nat "mo:base/Nat"; | ||
import Nat8 "mo:base/Nat8"; | ||
import Nat32 "mo:base/Nat32"; | ||
|
||
module { | ||
private let tablecrc32 : [Nat32] = [ | ||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, | ||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, | ||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, | ||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | ||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | ||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, | ||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, | ||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | ||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, | ||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | ||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, | ||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | ||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, | ||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, | ||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | ||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | ||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, | ||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, | ||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, | ||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | ||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, | ||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, | ||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, | ||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | ||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | ||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, | ||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, | ||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | ||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, | ||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | ||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, | ||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | ||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, | ||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, | ||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | ||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | ||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, | ||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, | ||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, | ||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | ||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, | ||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, | ||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d | ||
]; | ||
|
||
public func crc32(data : [Nat8]) : [Nat8] { | ||
var crc : Nat32 = 4294967295; | ||
for (byte in data.vals()) { | ||
crc := (crc >> 8) ^ tablecrc32[Nat32.toNat((crc ^ Nat32.fromNat(Nat8.toNat(byte))) & 0xFF)]; | ||
}; | ||
crc := (crc ^ 0xFFFFFFFF) & 0xffffffff; | ||
return [ | ||
Nat8.fromNat(Nat32.toNat((crc >> 24) & 0xFF)), | ||
Nat8.fromNat(Nat32.toNat((crc >> 16) & 0xFF)), | ||
Nat8.fromNat(Nat32.toNat((crc >> 8) & 0xFF)), | ||
Nat8.fromNat(Nat32.toNat((crc) & 0xFF)) | ||
]; | ||
}; | ||
}; |
Oops, something went wrong.