# What are the maths to convert bytes <-> trytes?

I've heard that one byte contains as much data as "about 5 trits". However, I'm not entirely clear on how the conversion works.

How do I convert binary data into balanced ternary (and vice versa)?

In particular, I am asking because I'd like to implement proper bytes <-> trytes conversion in PyOTA, but I don't understand how to handle edge cases (especially surrounding the "about 5 trits" part).

• mobilefish on youtube has some really great videos about the conversions Dec 9 '17 at 22:57
• That's a very good question. I do not understand the reason for negative vote. Who voted negative. Could you give more details of your vote? Dec 10 '17 at 18:11

There are several ways to convert bytes to trytes, caused by the fact that you can take a different number of bytes at once to convert (the more bytes you take, the less space is wasted).

In theory, you will need `log 256 / log 3 = 5.047438028571` trits for each byte.

# bytes as starting point

The implementation in ascii2trytes uses 1 byte and converts it to 2 trytes (6 trits), by dividing the byte value by 27 and using the remainder as first tryte and the division result as second tryte.

Then represent these trytes in balanced ternary (0 = `000`, 1 = `00+`, 2=`0+-` 3=`0+0`, 4=`0++`, 5=`+--`, etc.) if you really want trits :)

That way, every byte can be converted to trytes, but not every combination of trytes can be converted to bytes. One byte will use 6 trits.

This method is used to encode binary data (like small files) into a transaction message/signature.

# trytes as starting point

You can also start with trytes (this method is used to send a transaction - which consists of trytes - via UDP to the neighbors). In this case, create groups of 5 trits (if you have trytes, take every group of consecutive 5 trytes and make 3 groups of 5 trits from it), then encode them to a number from 0 to 242, and put them into a byte.

That way, every tryte combination can be converted to bytes, but there are some byte results (243 to 255) that are never achieved.

# bignum arithmetic

In case your language supports it, you can also use bignum arithmetic to convert an arbitrary number of bytes at once to trytes and vice versa. Just multiply by 256 or 27 and add the next tryte/byte. When you are finished (and have a really big number), divide by the other value (27 or 256) and thereby split the values apart. Note that when doing so, leading zero bytes (or trytes) may get lost during roundtrip conversion, so if that is an issue, add a byte (or tryte) with value 1 at the beginning (and strip it off after finishing the convesion back).

This method is essentially the same as you use when trying to output a huge binary number in decimal. While it works, I don't know any practical need in iota applications (since either you have trytes you need to transport-encode as bytes, or bytes you need to transport-encode as trytes, and the other two methods are fine for that).

• Thanks mihi! I must confess, I have an agenda behind asking this question (: Currently, PyOTA does use the ascii2trytes codec, but a number of users have been asking for a more... maths-y conversion process. I've updated my question with more info. Dec 9 '17 at 22:31
• I hope I have updated the answer accordingly.
– mihi
Dec 9 '17 at 23:57
• Thanks! I need to spend some time digesting this. I think an example would help me to understand better, but I think what you've posted so far will definitely help me figure this out! Dec 10 '17 at 2:21
• Hey @mihi I'm still trying to digest all of this. For the "trytes as a starting point" method, would it make sense to work with groups of 6 trits at a time, instead of 5? This way we could support all possible byte values, and it should also make it possible to decode values encoded using the "bytes as a starting point" method; am I thinking about this the right way? Dec 28 '17 at 19:04
• Hm. Ok, I see what you mean there; that makes sense. Maybe the part that I'm grappling with then, is how to design a codec such that `to_bytes(to_trits(bytes_value)) == bytes_value` (and mutatis mutandis), even when `bytes_value` contains bytes in the `[244,255]` range. Dec 30 '17 at 22:31