I need an efficient way to convert between numbers and text, preserving sort order.

The best idea that I have currently is to convert between Nat and 64-bit (16 chars) hex numbers: this is relatively efficient and preserves sort order.

Something more efficient?

To see a bigger picture, I need a type capable to represent multiple values flexibly. For example, 32 chars Text can represent two 64-bit integers. It is also possible to represent as Text a pair of a principal and a 64-bit number, etc. Maybe, there is a better way than to use Text?

Ah, sorry, when you wrote about multiple values in the last paragraph I forgot about the sort order requirement. Is the sort order really preserved the way you want it to be if you concatenate two numbers or a principal and a number?

With candid I believe it is not preserved because of little-endian encoding.

But I believe you can roll your own conversion and use type Blob (via [Nat8]). The type works for numbers and principals, the two examples you have given. And it is comparable with the sort order you want.

For Nats you would convert to Nat64 first and access the individual bytes with shift and/or mask operators and convert to a [Nat8].