Random Principals in Motoko - For Testing

I’m trying to decipher a Principal structure so that I can create some random principals in my tests.

import Principal "mo:base/Principal";
import Blob "mo:base/Blob";
import Debug "mo:base/Debug";

actor Echo  {

  // Say the given phase.
  public shared(msg) func test() : async ([Nat8],Text) {
    Debug.print(debug_show(Principal.fromActor(Echo)));
    return (
        Blob.toArray(
            Principal.toBlob(
                Principal.fromActor(Echo)
            )
        ), Principal.toText(Principal.fromActor(Echo)));
  };
};

This outputs something like (vec {0; 0; 0; 0; 0; 48; 0; 128; 1; 1}, “zwbmv-jyaaa-aaaab-qacaa-cai”). the last two numbers always seem to be 1 and only the 3rd to last and 5th to last seem to change much). What is the best way to be doing this? I seem to remember seeing the structure at some point. Is it 8 bytes and then two bytes of a check sum? How do I produce the check sum? I see libraries out there like motoko-crc/CRC8.mo at master · enzoh/motoko-crc · GitHub but they look old. Can I just swap out Word8 for Nat8 and spend a hash to a crc check of the hash like in Cyclic Redundancy Checks?

The principal format is speced here: The Internet Computer Interface Specification :: Internet Computer

If you need some random identities, you can use ic-repl's identity command. For example, here is the test script we use for CanCan: cancan/accessControl.test.sh at main · dfinity/cancan · GitHub

3 Likes

I had the problem of needing a bunch of principals for motoko unit testing today. I came up with this, anyone got another approach?

let principals = Array.tabulate<Principal>(
  10,
  func(i) {
    Principal.fromBlob(Blob.fromArray([Nat8.fromNat(i)]));
  },
);
2 Likes

off topic in Motoko… but in rust

#[ic_cdk_macros::update]

async fn getrandomprincipal() → String {
let bytes = raw_rand().await;
if bytes.is_ok() {
let bytes = bytes.unwrap();
let vbytes = bytes.0;
let slice = &vbytes[0…29];
let p = Principal::from_slice(slice);
return format!(“{}”, p.to_text());
}
format!(“NPT FOUND”)
}

1 Like

Is there a way to generate an identity/principal without switching to it?

As a workaround I’m immediately switching back to the identity I was previously using.

You can create a bunch of identities first, and then choose the one you want to use, e.g., identity alice; identity bob; identity cathy; ...

We don’t have a way to export identities yet. If you use dfx to create a bunch of pem files, you can use identity alice "a.pem" when you want to use it.

1 Like