A very simple bidirectional level translator can be made with a single N-mosfet:
The mosfet used should be a model with a low Vgs threshold, so that it can have a relatively low Rds-ON (ON resistance) at the intended input voltage level (3.3v in this case).
BSS138 in one such example, it has a Vgs-th of 1.5v max and is specified to have a low drain-source resistance with Vgs voltages as low as 2.5v (maybe slightly lower too).
The shown example uses 3.3v <-> 5v translation but it can also work with 2.5v <-> 3.3v or 2.5v <-> 5v, even between 2.5v <-> 12v. The range is only limited by the characteristics of the mosfet used.
The shown circuit is based on an application note from NXP
AN97055 Bi-directional level shifter for
I2C-bus and other systems
New shorter version: AN10441
Level shifting techniques in I2C-bus designNew shorter version: AN10441
Level shifting techniques in I2C-bus design
When L1 is high (3v3) or floating R1 keeps the mosfet off so R2 pulls the drain side high (to 5v).
When L1 is pulled low then the mosfet conducts and the drain becomes low.
When a low level (0) is applied to H1 then that voltage is transferred through the substrate diode to the source side (L1)
Please note that the resistance size can affect the speed (image source)
Alternative transistor solution
Relevant articles you may find useful: