Character codes and conversion
ord and chr, ASCII, comparing strings, and a Caesar cipher.
Covers OCR J277 2.2.2 Data types · AQA 8525 3.2.8 String handling operations in a programming language · Edexcel 1CP2 6.3.3 String manipulation
Do this lesson in the simulatorPrint it: worksheet (PDF) · answers (PDF) · as a web page
A computer stores only numbers. Every character you type, from A to ? to a space, is stored as a number called its character code. This lesson shows the codes, how to convert between characters and codes, and a secret message that works because letters are numbers.
ord and chr
ord gives the code for a character. chr gives the character for a code:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print(ord("A"), ord("B"), ord("Z"))
print(ord("a"), ord("z"))
print(ord("0"), ord(" "))
print(chr(66), chr(111), chr(116))
A is 65, B is 66, and the alphabet counts up from there, so Z is 90. Lower-case letters start at 97. The digit 0 is 48, and even a space has a code, 32. These are the codes of ASCII, the character set that the first 128 codes of Unicode still follow.
Letters are in order
Because the codes count up, you can do arithmetic on letters:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
letter = "C"
print("the next letter is", chr(ord(letter) + 1))
print("C is letter number", ord(letter) - ord("A") + 1, "of the alphabet")
print("upper to lower:", chr(ord(letter) + 32))
In ASCII, lower case is always 32 codes after upper case, so adding 32 does to a capital letter what lower() does. (lower() also knows the letters beyond ASCII, such as É.)
Comparing strings
Comparing strings with < and > compares their codes, one character at a time:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("apple" < "banana")
print("Zebra" < "apple")
print("robot" == "Robot")
"Zebra" < "apple" is True, because Z (90) comes before a (97). Capital letters sort before lower case. Convert both strings with lower() before comparing if case should not matter.
Turning digits into numbers, and back
int() and str() from lesson F1.8 convert whole strings. Under the hood, a digit is a character code too:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
reading = "42"
print(int(reading) + 1) # the whole string as a number
print(ord(reading[0]) - ord("0")) # the first digit, worked out from its code
print(str(99) + " red balloons")
print(reading.isdigit(), "4two".isdigit())
isdigit() asks whether every character is a digit, which lets a program check an answer before it calls int() and crashes.
A secret message
A Caesar cipher moves every letter a fixed number of places along the alphabet. With character codes it is a loop:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
message = "ROBOT"
shift = 3
secret = ""
for letter in message:
code = ord(letter) - ord("A") # 0 to 25
code = (code + shift) % 26 # move along, wrapping Z round to A
secret = secret + chr(code + ord("A"))
print(secret)
% 26 wraps the end of the alphabet round to the start, so X shifted by 3 is A. Change shift to -3 and put the secret back in message: it decodes.
Task: shift the letters
Ask Message? and print the message with every letter moved one place along the alphabet. The task answers HAL (the computer in a famous film), and the answer is the name of a famous computer company. The message will be capital letters only. Work it out with ord and chr.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
message = input("Message? ")
secret = ""
Challenges
- Print the whole alphabet with one loop and
chr, without typing any letters. - Make the cipher keep spaces as they are, so that
HELLO ROBOTworks. - Play a note for each letter of a name:
tone(ord(letter) * 5, 0.2). Which name sounds best?
Past paper questions on this
Real exam questions that test this, each worked through with a program you can run.
- AQA 8525 Sample Paper 1, Question 8: Output LOWER or NOT LOWER for a character 7 marks
- Edexcel 1CP2 June 2025 Paper 2, Question 3: Rearrange mixed-up lines: ASCII totals and a digit added by divisibility 15 marks
- Edexcel 1CP2 June 2024 Paper 2, Question 2: Choose the right lines to make a Caesar cipher with ord() and chr() 10 marks
- Edexcel 1CP2 June 2023 Paper 2, Question 5: A user ID: local and global names, a procedure, lower(), isdigit() and ord() 15 marks
- Edexcel 1CP2 June 2022 Paper 2, Question 1: Turn a number from 5 to 30 into a letter with chr(), with a range check 10 marks