Principal id (pid)

The generation of principal id (pid) is controlled internally by the IC system. Here you can find more details about the design of pid.

There are currently two main ways:

  1. Opaque ID randomly generated by the system

    This is the most common form. The system uses a random number generator to randomly generate a binary value of 0-29 bytes in length, and appends 0x01 at the end. This process is completely controlled internally by the system and cannot be influenced externally, so it is opaque externally. This type of ID is randomly generated.

  2. Self-authenticating ID based on a public key

    This type of pid requires an external public key, usually controlled by the user. The system will DER encode this public key, take the SHA-224 hash of it, and append 0x02 at the end to form a 29 byte Principal id. A user with the corresponding private key can then use this ID for authentication, signing and other operations.

  3. The system can also derive new ID from an existing Principal:

    Append a nonce to the Principal, compute the hash, and append 0x03. This generates an ID space that only that Principal can register.

  4. Anonymous ID

    These take the form 0x04, and are used by anonymous callers. They can send call and query requests to the IC network without signatures.

  5. Reserved ID

    Reserved ID are a special Principal format. They are not real ID, but have a similar format and provide more expressiveness for Dapps.


The format is: blob · 0x7f, where 0 ≤ |blob| < 29 (an arbitrary byte sequence of 0 - 28 bytes + 0x7f).

Reserved ID do not correspond to any real principals. Their purpose is for Dapps to reuse the text representation format of Principals, while explicitly indicating the ID does not point to a real canister or user.

For example, if a Dapp needs to display an ID that looks like a Principal but does not represent a real pid, it can construct a reserved ID like:

0x123456789520 + 0x7f

This generates a reserved ID that has a text representation like a Principal, but the Dapp and system know it does not correspond to a real principal.

The maximum length of a reserved ID is also 29 bytes, consistent with other forms of Principal ID. It is only constructed by Dapps, the system does not generate reserved ID when creating new Principal ID.


The text format of Principal is defined as follows:

  1. Compute a 4 byte CRC32 checksum of the raw principal binary value.
  2. Prepend the checksum to the Principal value.
  3. Base32 encode the concatenated result.
  4. Insert a "-" every 5 characters as a separator, for grouped display.
  5. Uniformly display in lowercase.

For example, for a Principal with ID 0xABCD01:

  1. Its CRC32 checksum is 0x233FF206.
  2. Base32 encoding the concatenated result gives em77ebvlzuaq.
  3. Inserting "-" every 5 chars, the text format is em77e-bvlzu-aq.

This format has many benefits:

  • Uniform display format suitable for different contexts
  • Fixed maximum length of 63 bytes, easy to process
  • CRC checksum can detect conversion errors
  • Case insensitive parsing