VP 21: ASCII and Bytes in Python (10 pts + 25 extra)

What You Need

Any Python 3 environment, such as Google Colab.

Purpose

To practice using ASCII encoding, bytes, and byte arrays.

Flags Fixed

The scoring engine had the wrong answers for flags VP 21.1 and VP 21.2. I fixed them on 9-4-24.

Google Colab

This is the new way to get a Python environment in the cloud, including an AI to help write your code.

In a browser, go to

https://colab.research.google.com/
If you see a blue "Sign In" button at the top right, click it and log into a Google account.

From the menu, click File, "New notebook".

ASCII TABLE

The table below, from Wikipedia, shows all the ASCII characters with their numerical values in Decimal and Hex representations.

Notice that "A" is 65 (in decimal) or 0x41 (in hex).

Bytes Objects

Execute this code:
a = b'ABC'
a0 = a[0]
print("a:", a, "type", type(a))
print("a0:", a, "type", type(a0))

a += b'D'
print("a:", a, "type", type(a))

a[1] = b'D'
As shown below, note these facts:

Bytearrays

Execute this code:
a = b'ABC'
ba = bytearray(a)
print("a:", a, "type", type(a))
print("ba:", ba, "type", type(ba))

ba[1] = 68
print("ba:", ba, "type", type(ba))
It's possible to modify a single byte in a bytearray, as shown below.

Unprintable Characters

Execute this code:
a = b''
for i in range(65, 70):
  a += i.to_bytes(1, 'big')
print("a:", a, "type", type(a))

a = b''
for i in range(5, 10):
  a += i.to_bytes(1, 'big')
print("a:", a, "type", type(a))
As shown below, note these facts:

Example: Caesar Cipher

This is an ancient cryptographic system which was regarded as military-grade security 2100 years ago.

It works by simply moving the letters forward three spaces in the alphabet.

Encryption

Execute this code:
plaintext = b'HELLO'

# how many letters to shift by
shift = 3

ciphertext = b''
for c in plaintext:
  ciphertext += (c + shift).to_bytes(1, 'big')

print(ciphertext)
The encrypted version of 'HELLO' is 'KHOOR', as shown below.

Decryption

Execute this code:
ciphertext = b'KHOOR'

# how many letters to shift by
shift = 3

plaintext = b''
for c in ciphertext:
  plaintext += (c - shift).to_bytes(1, 'big')

print(plaintext)
The decrypted version of 'KHOOR' is 'HELLO', as shown below.

Bytes and Hex Strings

Often you have data as a long string of hex characters, and you want to manipulate it as a bytes object.

Here's how to perform that conversion.

Execute this code:

# Convert from hex to bytes
hex_string = '48656c6c6f'
print("Input is:", hex_string, type(hex_string))
bytes_version = bytes.fromhex(hex_string)
print(bytes_version, type(bytes_version))

# Convert from bytes to hex
bytes_version = b'WALDO'
print("Input is:", bytes_version, type(bytes_version))
hex_string = bytes_version.hex()
print(hex_string, type(hex_string))
The conversions succeed, as shown below.

Flag VP 21.1: Hex (5 pts)

Convert this hex string to readable text to reveal the flag.
54686520666c61672069732057484f4f504545

Flag VP 21.2: Caesar (5 pts)

This text is encrypted with the Caesar cipher. Decrypt it to reveal the flag.
FRZDEXQJD

Flag VP 21.3: Better Caesar (10 pts)

This text is encrypted with a Caesar cipher with these properties:
  • You don't know the shift value. It could be any value from 1 to 25.
  • The alphabet is wrapped, so shifting Z by 1 produces A
  • Spaces are left unchanged
Decrypt this ciphertext to reveal the flag.
ESP QWLR TD KZCZLDEPC

Flag VP 21.4: Adding (15 pts)

Convert these two hex strings to bytes objects. Then add them together byte by byte. Convert the result to ASCII to reveal the flag.
0e140311100302040a0308020f01070b070811060e0a090d0c
4654620f56695f6316666b1e33584d3a583a4859344f4b3822


Posted: 8-25-24
Flags 1 and 2 fixed 9-4-24
Video added 10-9-24