Levenshtein coding is asymptotically optimal and preserves the ordering. It also has short codes for zero (0) and one (10) . It's not optimal for numbers in between (like 256 end 65536). It's also not that hard to implement.