Encoding string one byte at a time?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Encoding string one byte at a time?

Post by Chris Corbyn »

I need to encode a string one byte at a time for memory saving reasons. I'm encoding as base64 but base64 encoding a string with a sequence of characters does not yield the same result as encoding the string byte for byte and concatenating the result.

I'm doing this so I can fread() one byte from a file at a time rather than grabbing the file's full contents during encoding. Anybody know a way to do this?

Here's a failing test case

Code: Select all

<?php

class TestOfEncoder extends UnitTestCase
{
	protected function makeString($len)
	{
		$ret = "";
		$chr = 32;
		for ($i = 0; $i < $len; $i++) //cycle through the ascii sequence
		{
			$ret .= chr($chr++);
			if ($chr >= 126) $chr = 32;
		}
		return $ret;
	}
	
	public function testBase64EncodingByteForByteMatchesEncodingFullString()
	{
		$string = $this->makeString(100);
		$raw_encoded = base64_encode($string);
		
		$byte_encoded = "";
		for ($char = 0, $len = strlen($string); $char < $len; $char++)
		{
			$byte_encoded .= base64_encode($string{$char});
		}
		
		$this->assertEqual($raw_encoded, $byte_encoded);
	}
}

Code: Select all

Fail: TestOfEncoder -> testBase64EncodingByteForByteMatchesEncodingFullString -> Equal expectation fails at character 1 with [ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fSAhIiMkJQ==] and [IA==IQ==Ig==Iw==JA==JQ==Jg==Jw==KA==KQ==Kg==Kw==LA==LQ==Lg==Lw==MA==MQ==Mg==Mw==NA==NQ==Ng==Nw==OA==OQ==Og==Ow==PA==PQ==Pg==Pw==QA==QQ==Qg==Qw==RA==RQ==Rg==Rw==SA==SQ==Sg==Sw==TA==TQ==Tg==Tw==UA==UQ==...] at [/Users/d11wtq/public_html/swiftmailer/branches/v3/tests/units/testcases/TestOfEncoder.php line 28]
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Ok, I hope this isn't a complete "fudge" (I need to do more tests) but on the premise the base64 returns 4 bytes for every 3 it receives I changed to:

Code: Select all

//
	public function testBase64EncodingByteForByteMatchesEncodingFullString()
	{
		$string = $this->makeString(100);
		$raw_encoded = base64_encode($string);
		
		$byte_encoded = "";
		for ($char = 0, $len = strlen($string); $char < $len; $char+=3)
		{
			$byte_encoded .= base64_encode(substr($string, $char, 3));
		}
		
		$this->assertEqual($raw_encoded, $byte_encoded);
	}
Voila! It worked.
Post Reply