def test_get_num_beyond_eos(self): """ Test than trying to read beyond the end of the stream raises an exception when calling get_num(...). """ bitstream = BitStream() # Store a 64-bit integer in the stream. num = int('00000000000000110101011001010011' '00101100001000101000100110101111', 2) bitstream.put_num(num, 64) # Check that trying to read 65 bits from the beginning of the stream # raises NotEnoughBitsInStreamError bitstream.seek(0) self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_num, 65) # An invalid read call should not move the position indicator. self.assertEquals(bitstream.get_current_pos(), 0) # Check that trying to read 33 bits from the middle of the stream # (pos = 32) raises NotEnoughBitsInStreamError bitstream.seek(32) self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_num, 33) # An invalid read call should not move the position indicator. self.assertEquals(bitstream.get_current_pos(), 32) # Check that trying to read a single bit while at the end of the stream # raises NotEnoughBitsInStreamError bitstream.seek(64) self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_num, 1) # An invalid read call should not move the position indicator. self.assertEquals(bitstream.get_current_pos(), 64)
def test_get_num_beyond_eos(self): """ Test than trying to read beyond the end of the stream raises an exception when calling get_num(...). """ bitstream = BitStream() # Store a 64-bit integer in the stream. num = int( '00000000000000110101011001010011' '00101100001000101000100110101111', 2) bitstream.put_num(num, 64) # Check that trying to read 65 bits from the beginning of the stream # raises NotEnoughBitsInStreamError bitstream.seek(0) self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_num, 65) # An invalid read call should not move the position indicator. self.assertEquals(bitstream.get_current_pos(), 0) # Check that trying to read 33 bits from the middle of the stream # (pos = 32) raises NotEnoughBitsInStreamError bitstream.seek(32) self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_num, 33) # An invalid read call should not move the position indicator. self.assertEquals(bitstream.get_current_pos(), 32) # Check that trying to read a single bit while at the end of the stream # raises NotEnoughBitsInStreamError bitstream.seek(64) self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_num, 1) # An invalid read call should not move the position indicator. self.assertEquals(bitstream.get_current_pos(), 64)
def test_byte_basic(self): """ Test basic put_byte and get_byte behavior. """ bitstream = BitStream() # Put a couple of bytes in the stream: bytes = [ 12, # 00001100 222, # 11011110 145, # 10010001 42, # 00101010 0, # 00000000 255] # 11111111 for byte in bytes: bitstream.put_byte(byte) # Sanity check: self.assertEquals(bitstream.get_length(),len(bytes)*8) self.assertEquals(bitstream.get_current_pos(),len(bytes)*8) # Read the bytes back from the stream bitstream.seek(0) for byte in bytes: self.assertEquals(bitstream.get_byte(), byte) # Read some bits from the stream, interpreting them as bytes, but # without restricting ourselves to 8-bit aligned bytes # e.g. read the "byte" defined by bits #4 to #12 bitstream.seek(4) self.assertEquals(bitstream.get_byte(), 205) # 11001101 bitstream.seek(19) self.assertEquals(bitstream.get_byte(), 137) # 10001001
def test_stress(self): """ Stress test BitStream by writings lots of numbers of different bit sizes and reading them back. """ # num_writes = 10000 num_writes = 1000 min_bit_length = 1 max_bit_length = 8192 # Generate the numbers nums = [] total_bit_length = 0 for i in range(0, num_writes): bit_length = random.randint(min_bit_length, max_bit_length) total_bit_length += bit_length val = random.randint(0, 2**bit_length - 1) nums.append({"bit_length": bit_length, "value": val}) # Write them to a BitStream object bitstream = BitStream() for num in nums: bitstream.put_num(num["value"], num["bit_length"]) # Check the BitStream length and current position self.assertEquals(bitstream.get_length(), total_bit_length) self.assertEquals(bitstream.get_current_pos(), total_bit_length) # Read all numbers back bitstream.seek(0) for num in nums: self.assertEquals(bitstream.get_num(num["bit_length"]), num["value"])
def test_put_bitstream_copy_self(self): """ Test using the put_bitstream_copy method with the same BitStream object as origin and destination. """ bitstream = BitStream() # Generate a random string of bits, ie: ('0' | '1')* num_bits = 50 bits = "" for i in range(0, num_bits): bits += random.choice( ('0', '1')) # inefficient, but ok for a test. # Put those bits in the BitStream... bitstream.put_bit_dump_string(bits) # ... copy the bitstream into itself at any point: bitstream.seek(random.randint(0, 50)) bitstream.put_bitstream_copy(bitstream) # Check that the bitstream was unchanged by the previous operation: # (overwriting data with the same data is the same as doing nothing, # except that the current position is changed to the end of the stream) self.assertEquals(bitstream.get_length(), num_bits) self.assertEquals(bitstream.get_current_pos(), num_bits) bitstream.seek(0) read_bits = bitstream.get_bit_dump_string(bitstream.get_length()) self.assertEqual(read_bits, bits)
def test_put_bitstream_copy_self(self): """ Test using the put_bitstream_copy method with the same BitStream object as origin and destination. """ bitstream = BitStream() # Generate a random string of bits, ie: ('0' | '1')* num_bits = 50 bits = "" for i in range(0,num_bits): bits += random.choice(('0','1')) # inefficient, but ok for a test. # Put those bits in the BitStream... bitstream.put_bit_dump_string(bits) # ... copy the bitstream into itself at any point: bitstream.seek(random.randint(0,50)) bitstream.put_bitstream_copy(bitstream) # Check that the bitstream was unchanged by the previous operation: # (overwriting data with the same data is the same as doing nothing, # except that the current position is changed to the end of the stream) self.assertEquals(bitstream.get_length(),num_bits) self.assertEquals(bitstream.get_current_pos(),num_bits) bitstream.seek(0) read_bits = bitstream.get_bit_dump_string(bitstream.get_length()) self.assertEqual(read_bits, bits)
def test_string_ascii(self): """ Test basic put_string and get_string behavior, using ASCII strings. """ bitstream = BitStream() string1 = "Test string " # 12 chars/bytes string2 = "using only ASCII characters (0-126):\n\t" # 38 chars/bytes string3 = "Hello World!" # 12 chars/bytes # Store our message in 3 writes bitstream.put_string(string1) bitstream.put_string(string2) bitstream.put_string(string3) # Sanity check: self.assertEquals(bitstream.get_length(), (12 + 38 + 12) * 8) self.assertEquals(bitstream.get_current_pos(), (12 + 38 + 12) * 8) # Retrieve our message in 2 reads bitstream.seek(0) self.assertEquals( bitstream.get_string(29 * 8), # read 29 bytes "Test string using only ASCII ") self.assertEquals( bitstream.get_string(33 * 8), # read 33 bytes "characters (0-126):\n\tHello World!")
def test_stress(self): """ Stress test BitStream by writings lots of numbers of different bit sizes and reading them back. """ # num_writes = 10000 num_writes = 1000 min_bit_length = 1 max_bit_length = 8192 # Generate the numbers nums = [] total_bit_length = 0 for i in range(0, num_writes): bit_length = random.randint(min_bit_length, max_bit_length) total_bit_length += bit_length val = random.randint(0, 2**bit_length - 1) nums.append({"bit_length" : bit_length, "value" : val}) # Write them to a BitStream object bitstream = BitStream() for num in nums: bitstream.put_num(num["value"], num["bit_length"]) # Check the BitStream length and current position self.assertEquals(bitstream.get_length(),total_bit_length) self.assertEquals(bitstream.get_current_pos(),total_bit_length) # Read all numbers back bitstream.seek(0) for num in nums: self.assertEquals(bitstream.get_num(num["bit_length"]),num["value"])
def test_get_byte_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_byte(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_byte) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0) bitstream.put_byte(14) bitstream.seek(1) # Read a single bit beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_byte) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),1)
def test_get_hex_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_hex(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_hex, 1) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0) bitstream.put_hex("DfF7CE69fF5478A") # 15 digits, 60 bits bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_hex, 61) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0)
def test_seek_negative_position(self): """ Test that seeking to a negative position raises an error. """ bitstream = BitStream() self.assertRaises(SeekOutOfRangeError, bitstream.seek, -1) # An invalid seek(...) call should not move the position indicator. self.assertEqual(bitstream.get_current_pos(), 0)
def test_get_base64_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_base64(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 8) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0) bitstream.put_base64("Zm9vYmE=") # 40 bits bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 48) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0)
def test_get_byte_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_byte(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_byte) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0) bitstream.put_byte(14) bitstream.seek(1) # Read a single bit beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_byte) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 1)
def test_seek_negative_position(self): """ Test that seeking to a negative position raises an error. """ bitstream = BitStream() self.assertRaises(SeekOutOfRangeError, bitstream.seek, -1) # An invalid seek(...) call should not move the position indicator. self.assertEqual(bitstream.get_current_pos(), 0)
def test_get_string_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_string(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_string, 1) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0) bitstream.put_string("Hello World!") # 12 chars/bytes bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_string, 13 * 8) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0)
def test_bitstream_constructor(self): """ Test that creating an empty bitstream succeeds. """ bitstream = BitStream() # An empty bitstream has length 0 ... self.assertEqual(bitstream.get_length(), 0) # ...and has its current position marker at position 0. self.assertEqual(bitstream.get_current_pos(), 0)
def test_get_string_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_string(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_string, 1) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0) bitstream.put_string("Hello World!") # 12 chars/bytes bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_string, 13*8) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0)
def test_bitstream_constructor(self): """ Test that creating an empty bitstream succeeds. """ bitstream = BitStream() # An empty bitstream has length 0 ... self.assertEqual(bitstream.get_length(), 0) # ...and has its current position marker at position 0. self.assertEqual(bitstream.get_current_pos(), 0)
def test_put_bitstream_copy(self): """ Test the basic functionality of the put_bitstream_copy method. """ bitstream1 = BitStream() bitstream1.put_string("This is bitstream1") bitstream2 = BitStream() bitstream2.put_string("This is bitstream2") bitstream3 = BitStream() # bitstream3 remains empty bitstream4 = BitStream() bitstream4.put_string("This is bitstream4") # copy the full contents of bitstream2 to the end of bitstream1 bitstream2.seek(0) bitstream1.put_bitstream_copy(bitstream2) self.assertEquals(bitstream2.get_current_pos(), bitstream2.get_length()) # check the contents of bitstream1 bitstream1.seek(0) self.assertEquals(bitstream1.get_string(bitstream1.get_length()), "This is bitstream1This is bitstream2") # copy the full contents of bitstream3 (aka. nothing) to the end of # bitstream4 bitstream3.seek(0) bitstream4.put_bitstream_copy(bitstream3) # check the contents of bitstream4 bitstream4.seek(0) self.assertEquals(bitstream4.get_string(bitstream4.get_length()), "This is bitstream4") # copy the contents of bitstream4 from the position 8 onwards bitstream4.seek(8 * 8) bitstream1.put_bitstream_copy(bitstream4) self.assertEquals(bitstream4.get_current_pos(), bitstream4.get_length()) # check the contents of bitstream1 bitstream1.seek(0) self.assertEquals(bitstream1.get_string(bitstream1.get_length()), "This is bitstream1This is bitstream2bitstream4")
def test_get_hex_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_hex(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_hex, 1) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0) bitstream.put_hex("DfF7CE69fF5478A") # 15 digits, 60 bits bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_hex, 61) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0)
def test_get_base64_beyond_eos(self): """ Test that trying to read beyond the end of the stream raises an exception when calling get_base64(...). """ bitstream = BitStream() self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 8) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0) bitstream.put_base64("Zm9vYmE=") # 40 bits bitstream.seek(0) # Read beyond EOS self.assertRaises(NotEnoughBitsInStreamError, bitstream.get_base64, 48) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0)
def test_put_bitstream_copy(self): """ Test the basic functionality of the put_bitstream_copy method. """ bitstream1 = BitStream() bitstream1.put_string("This is bitstream1") bitstream2 = BitStream() bitstream2.put_string("This is bitstream2") bitstream3 = BitStream() # bitstream3 remains empty bitstream4 = BitStream() bitstream4.put_string("This is bitstream4") # copy the full contents of bitstream2 to the end of bitstream1 bitstream2.seek(0) bitstream1.put_bitstream_copy(bitstream2) self.assertEquals(bitstream2.get_current_pos(), bitstream2.get_length()) # check the contents of bitstream1 bitstream1.seek(0) self.assertEquals(bitstream1.get_string(bitstream1.get_length()), "This is bitstream1This is bitstream2") # copy the full contents of bitstream3 (aka. nothing) to the end of # bitstream4 bitstream3.seek(0) bitstream4.put_bitstream_copy(bitstream3) # check the contents of bitstream4 bitstream4.seek(0) self.assertEquals(bitstream4.get_string(bitstream4.get_length()), "This is bitstream4") # copy the contents of bitstream4 from the position 8 onwards bitstream4.seek(8*8) bitstream1.put_bitstream_copy(bitstream4) self.assertEquals(bitstream4.get_current_pos(), bitstream4.get_length()) # check the contents of bitstream1 bitstream1.seek(0) self.assertEquals(bitstream1.get_string(bitstream1.get_length()), "This is bitstream1This is bitstream2bitstream4")
def test_base64_basic(self): """ This method tests put_base64's and get_base64's basic functionality. """ bitstream = BitStream() # We use the Base64 Test Vectors defined in RFC4648. # http://www.ietf.org/rfc/rfc4648.txt test_vectors = [("",""), ("f","Zg=="), ("fo","Zm8="), ("foo","Zm9v"), ("foob","Zm9vYg=="), ("fooba","Zm9vYmE="), ("foobar","Zm9vYmFy")] # STEP 1: # For each test vector, we write its value to the bitstream as a string # then read it as base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val)*8 bitstream.put_string(str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # NOTE that we are overwriting multiple times our bitstream, this is # also a feature of BitStream we are testing in this test case. # STEP 2: # For each test vector, we write its value to the bitstream as base64 # data, then read it as string *and* base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val)*8 bitstream.put_base64(base64_val) bitstream.seek(0) self.assertEquals(bitstream.get_string(vector_bit_length), str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # STEP 3: # For each test vector, we write its value to a NEW bitstream as base64 # data, and make sure the length of the stream is the expected one. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val)*8 new_bs = BitStream() new_bs.put_base64(base64_val) self.assertEquals(new_bs.get_length(), vector_bit_length) self.assertEquals(new_bs.get_current_pos(), vector_bit_length)
def test_seek_beyond_eos(self): """ Test that seeking beyond the end of the bitstream results in an exception raised. """ bitstream = BitStream() self.assertRaises(SeekOutOfRangeError, bitstream.seek, 1) # empty stream # An invalid seek(...) call should not move the position indicator. self.assertEqual(bitstream.get_current_pos(), 0) # Store a 64-bit integer in the stream. num = int('00000000000000110101011001010011' '00101100001000101000100110101111', 2) bitstream.put_num(num, 64) # Test seeking past 64 bits self.assertRaises(SeekOutOfRangeError, bitstream.seek, 65) self.assertRaises(SeekOutOfRangeError, bitstream.seek, random.randint(66,2**128)) # An invalid seek(...) call should not move the position indicator. self.assertEqual(bitstream.get_current_pos(), 64)
def test_get_string_non_bytable_size(self): """ Test that calling get_string with a bit_length that is not a multiple of 8 raises an exception. That is, we cannot read partial bytes as string data. """ bitstream = BitStream() bitstream.put_string("Hello World!") bitstream.seek(0) self.assertRaises(ValueError, bitstream.get_string, 18) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(),0)
def test_get_string_non_bytable_size(self): """ Test that calling get_string with a bit_length that is not a multiple of 8 raises an exception. That is, we cannot read partial bytes as string data. """ bitstream = BitStream() bitstream.put_string("Hello World!") bitstream.seek(0) self.assertRaises(ValueError, bitstream.get_string, 18) # Current position should not have been changed self.assertEquals(bitstream.get_current_pos(), 0)
def test_seek_beyond_eos(self): """ Test that seeking beyond the end of the bitstream results in an exception raised. """ bitstream = BitStream() self.assertRaises(SeekOutOfRangeError, bitstream.seek, 1) # empty stream # An invalid seek(...) call should not move the position indicator. self.assertEqual(bitstream.get_current_pos(), 0) # Store a 64-bit integer in the stream. num = int( '00000000000000110101011001010011' '00101100001000101000100110101111', 2) bitstream.put_num(num, 64) # Test seeking past 64 bits self.assertRaises(SeekOutOfRangeError, bitstream.seek, 65) self.assertRaises(SeekOutOfRangeError, bitstream.seek, random.randint(66, 2**128)) # An invalid seek(...) call should not move the position indicator. self.assertEqual(bitstream.get_current_pos(), 64)
def test_base64_basic(self): """ This method tests put_base64's and get_base64's basic functionality. """ bitstream = BitStream() # We use the Base64 Test Vectors defined in RFC4648. # http://www.ietf.org/rfc/rfc4648.txt test_vectors = [("", ""), ("f", "Zg=="), ("fo", "Zm8="), ("foo", "Zm9v"), ("foob", "Zm9vYg=="), ("fooba", "Zm9vYmE="), ("foobar", "Zm9vYmFy")] # STEP 1: # For each test vector, we write its value to the bitstream as a string # then read it as base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val) * 8 bitstream.put_string(str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # NOTE that we are overwriting multiple times our bitstream, this is # also a feature of BitStream we are testing in this test case. # STEP 2: # For each test vector, we write its value to the bitstream as base64 # data, then read it as string *and* base64 data. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val) * 8 bitstream.put_base64(base64_val) bitstream.seek(0) self.assertEquals(bitstream.get_string(vector_bit_length), str_val) bitstream.seek(0) self.assertEquals(bitstream.get_base64(vector_bit_length), base64_val) bitstream.seek(0) # STEP 3: # For each test vector, we write its value to a NEW bitstream as base64 # data, and make sure the length of the stream is the expected one. for (str_val, base64_val) in test_vectors: vector_bit_length = len(str_val) * 8 new_bs = BitStream() new_bs.put_base64(base64_val) self.assertEquals(new_bs.get_length(), vector_bit_length) self.assertEquals(new_bs.get_current_pos(), vector_bit_length)
def test_put_hex_invalid_format(self): """ Test that put_hex raises an exception when passed any string not of the form ('0'-'9'|'a'-'f'|'A'-'F')* """ bitstream = BitStream() # Try some fixed examples self.assertRaises(ValueError, bitstream.put_hex, "aF92G2") self.assertRaises(ValueError, bitstream.put_hex, "Hello") self.assertRaises(ValueError, bitstream.put_hex, "3354 F") self.assertRaises(ValueError, bitstream.put_hex, "ケコサシス") # Generate a random string conforming to ('0'-'9'|'a'-'f'|'A'-'F')* # except for one (ascii) character. valid_hex_digits = "0123456789abcdefABCDEF" num_digits = 50 pos_wrong_char = random.randint(1,48) r_invalid_hex_string = "" for i in range(0,pos_wrong_char): r_invalid_hex_string += random.choice(valid_hex_digits) non_hex_char = "0" while(non_hex_char in valid_hex_digits): non_hex_char = \ random.choice(string.letters + string.digits + string.whitespace) r_invalid_hex_string += non_hex_char for i in range(0,num_digits - pos_wrong_char - 1): r_invalid_hex_string += random.choice(valid_hex_digits) # Try the randomly generated example self.assertRaises(ValueError, bitstream.put_hex, r_invalid_hex_string) # Calls that throw exceptions should not alter the contents or position # of the bitstream: self.assertEquals(bitstream.get_length(),0) self.assertEquals(bitstream.get_current_pos(),0)
def test_put_hex_invalid_format(self): """ Test that put_hex raises an exception when passed any string not of the form ('0'-'9'|'a'-'f'|'A'-'F')* """ bitstream = BitStream() # Try some fixed examples self.assertRaises(ValueError, bitstream.put_hex, "aF92G2") self.assertRaises(ValueError, bitstream.put_hex, "Hello") self.assertRaises(ValueError, bitstream.put_hex, "3354 F") self.assertRaises(ValueError, bitstream.put_hex, "ケコサシス") # Generate a random string conforming to ('0'-'9'|'a'-'f'|'A'-'F')* # except for one (ascii) character. valid_hex_digits = "0123456789abcdefABCDEF" num_digits = 50 pos_wrong_char = random.randint(1, 48) r_invalid_hex_string = "" for i in range(0, pos_wrong_char): r_invalid_hex_string += random.choice(valid_hex_digits) non_hex_char = "0" while (non_hex_char in valid_hex_digits): non_hex_char = \ random.choice(string.letters + string.digits + string.whitespace) r_invalid_hex_string += non_hex_char for i in range(0, num_digits - pos_wrong_char - 1): r_invalid_hex_string += random.choice(valid_hex_digits) # Try the randomly generated example self.assertRaises(ValueError, bitstream.put_hex, r_invalid_hex_string) # Calls that throw exceptions should not alter the contents or position # of the bitstream: self.assertEquals(bitstream.get_length(), 0) self.assertEquals(bitstream.get_current_pos(), 0)
def test_string_utf8(self): """ Test basic put_string and get_string support for UTF-8 strings. """ bitstream = BitStream() string1 = "ÄäÜüß" # 5 chars, 10 bytes string2 = "ЯБГДЖЙŁĄŻĘĆŃŚŹ" # 14 chars, 28 bytes string3 = "てすとアイウエオカキクケコサシスセソタチツテ" # 22 chars, 66 bytes # Store our message in 3 writes bitstream.put_string(string1) bitstream.put_string(string2) bitstream.put_string(string3) # Sanity check: self.assertEquals(bitstream.get_length(),(10+28+66)*8) self.assertEquals(bitstream.get_current_pos(),(10+28+66)*8) # Retrieve the whole message bitstream.seek(0) self.assertEquals(bitstream.get_string(bitstream.get_length()), "ÄäÜüßЯБГДЖЙŁĄŻĘĆŃŚŹてすとアイウエオカキクケコサシスセソタチツテ")
def test_string_utf8(self): """ Test basic put_string and get_string support for UTF-8 strings. """ bitstream = BitStream() string1 = "ÄäÜüß" # 5 chars, 10 bytes string2 = "ЯБГДЖЙŁĄŻĘĆŃŚŹ" # 14 chars, 28 bytes string3 = "てすとアイウエオカキクケコサシスセソタチツテ" # 22 chars, 66 bytes # Store our message in 3 writes bitstream.put_string(string1) bitstream.put_string(string2) bitstream.put_string(string3) # Sanity check: self.assertEquals(bitstream.get_length(), (10 + 28 + 66) * 8) self.assertEquals(bitstream.get_current_pos(), (10 + 28 + 66) * 8) # Retrieve the whole message bitstream.seek(0) self.assertEquals(bitstream.get_string(bitstream.get_length()), "ÄäÜüßЯБГДЖЙŁĄŻĘĆŃŚŹてすとアイウエオカキクケコサシスセソタチツテ")
def test_byte_basic(self): """ Test basic put_byte and get_byte behavior. """ bitstream = BitStream() # Put a couple of bytes in the stream: bytes = [ 12, # 00001100 222, # 11011110 145, # 10010001 42, # 00101010 0, # 00000000 255 ] # 11111111 for byte in bytes: bitstream.put_byte(byte) # Sanity check: self.assertEquals(bitstream.get_length(), len(bytes) * 8) self.assertEquals(bitstream.get_current_pos(), len(bytes) * 8) # Read the bytes back from the stream bitstream.seek(0) for byte in bytes: self.assertEquals(bitstream.get_byte(), byte) # Read some bits from the stream, interpreting them as bytes, but # without restricting ourselves to 8-bit aligned bytes # e.g. read the "byte" defined by bits #4 to #12 bitstream.seek(4) self.assertEquals(bitstream.get_byte(), 205) # 11001101 bitstream.seek(19) self.assertEquals(bitstream.get_byte(), 137) # 10001001
def test_put_bit_dump_string_invalid_format(self): """ Test that put_bit_dump_string raises an exception when passed any string not of the form ('0'|'1')* """ bitstream = BitStream() # Try some fixed examples self.assertRaises(ValueError, bitstream.put_bit_dump_string, "23234") self.assertRaises(ValueError, bitstream.put_bit_dump_string, "Hello") self.assertRaises(ValueError, bitstream.put_bit_dump_string, "0101 0") self.assertRaises(ValueError, bitstream.put_bit_dump_string, "ケコサシス") # Generate a random string conforming to ('0'|'1')* except for one # (ascii) character. num_bits = 50 pos_wrong_char = random.randint(1,48) r_invalid_bit_string = "" for i in range(0,pos_wrong_char): r_invalid_bit_string += random.choice(('0','1')) r_invalid_bit_string += \ random.choice(string.letters + "23456789_-/\\" + string.whitespace) for i in range(0,num_bits - pos_wrong_char - 1): r_invalid_bit_string += random.choice(('0','1')) # Try the randomly generated example self.assertRaises(ValueError, bitstream.put_bit_dump_string, r_invalid_bit_string) # Calls that throw exceptions should not alter the contents or position # of the bitstream: self.assertEquals(bitstream.get_length(),0) self.assertEquals(bitstream.get_current_pos(),0)
def test_string_ascii(self): """ Test basic put_string and get_string behavior, using ASCII strings. """ bitstream = BitStream() string1 = "Test string " # 12 chars/bytes string2 = "using only ASCII characters (0-126):\n\t" # 38 chars/bytes string3 = "Hello World!" # 12 chars/bytes # Store our message in 3 writes bitstream.put_string(string1) bitstream.put_string(string2) bitstream.put_string(string3) # Sanity check: self.assertEquals(bitstream.get_length(),(12+38+12)*8) self.assertEquals(bitstream.get_current_pos(),(12+38+12)*8) # Retrieve our message in 2 reads bitstream.seek(0) self.assertEquals(bitstream.get_string(29*8), # read 29 bytes "Test string using only ASCII ") self.assertEquals(bitstream.get_string(33*8), # read 33 bytes "characters (0-126):\n\tHello World!")
def test_put_bit_dump_string_invalid_format(self): """ Test that put_bit_dump_string raises an exception when passed any string not of the form ('0'|'1')* """ bitstream = BitStream() # Try some fixed examples self.assertRaises(ValueError, bitstream.put_bit_dump_string, "23234") self.assertRaises(ValueError, bitstream.put_bit_dump_string, "Hello") self.assertRaises(ValueError, bitstream.put_bit_dump_string, "0101 0") self.assertRaises(ValueError, bitstream.put_bit_dump_string, "ケコサシス") # Generate a random string conforming to ('0'|'1')* except for one # (ascii) character. num_bits = 50 pos_wrong_char = random.randint(1, 48) r_invalid_bit_string = "" for i in range(0, pos_wrong_char): r_invalid_bit_string += random.choice(('0', '1')) r_invalid_bit_string += \ random.choice(string.letters + "23456789_-/\\" + string.whitespace) for i in range(0, num_bits - pos_wrong_char - 1): r_invalid_bit_string += random.choice(('0', '1')) # Try the randomly generated example self.assertRaises(ValueError, bitstream.put_bit_dump_string, r_invalid_bit_string) # Calls that throw exceptions should not alter the contents or position # of the bitstream: self.assertEquals(bitstream.get_length(), 0) self.assertEquals(bitstream.get_current_pos(), 0)