**Smalltalk**

There is a library yet ported to several Smalltalk dialects (Visualworks, Gemstone Squeak/Pharo, ...) named [Xtreams][1] that makes this task more than easy.

FileStream would be as simple as `'foo' asFilename reading` and `'bar' asFilename writing` for example in Visualworks, but are dialect specific.<br>
For this reason I demonstrate the algorithm with dialect neutral internal Streams instead.<br>
A good idea could be to process each byte code in increasing order:

	| input |
	input := 'Hello world' asByteArray reading.
	^((ByteArray new writing)
		write: ((0 to: 255) inject: ByteArray new reading into: [:outputSoFar :code |
			| nextOutput |
			nextOutput := ByteArray new writing.
			((input += 0; selecting: [:c | c <= code]) ending: code inclusive: true) slicing do: [:subStream |
				| positionable |
				positionable := subStream positioning.
				nextOutput write: (outputSoFar limiting: (positionable ending: code) rest size).
				nextOutput write: (positionable += 0; selecting: [:c | c = code])].
			nextOutput conclusion reading]);
		conclusion) asString

Of course, it is also possible to process in random order, but i'm afraid that it makes the code a bit too compact:

	| input output |
	input := 'Hello world' asByteArray reading.
	output := ByteArray new writing.
	(0 to: 255) asArray shuffled do: [:code |
			output += 0.
			(input += 0; ending: code inclusive: true) slicing do: [:subStream |
				| positionable |
				positionable := subStream positioning.
				output ++ (positionable += 0; rejecting: [:c | c = code]) rest size.
				output write: (positionable += 0; selecting: [:c | c = code])]].
	^output conclusion asString

**EDIT**

Ah stupid me, I didn't saw the log2 solution:

	| input output |
	input := 'Hello world' asByteArray reading.
	(output := ByteArray new writing) write: (input collecting: [:e | 0]).
	output := (0 to: 7) asArray shuffled inject: output into: [:outputSoFar :bit |
			(ByteArray new writing)
				write:
					(((input += 0; collecting: [:e | e >> bit bitAnd: 1]) interleaving: outputSoFar conclusion reading) 
						transforming: [ :in :out | out put: in get << bit + in get]);
				yourself].
	^output conclusion asString
  [1]: https://code.google.com/p/xtreams/