Students send messages with a checksum, see the receiver reject a changed one, and learn why a keyed checksum is needed against deliberate changes.
Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.
Predict and Run 8 min · Investigate 10 min · Modify 7 min · Make 17 min
The idea: privacy (encryption) and integrity (nobody changed it) are different jobs. A checksum is a small number worked out from the message and sent with it; a mismatch means the message changed.
Everyday picture: counting the cards when you hand over a pack. Say there are 52; if the receiver counts 51, something is missing. Where it breaks: if someone swaps a card for another, the count is still 52.
Honest limits: this checksum is deliberately simple. It ignores the order of letters (Investigate task 2), only has ten values (a changed message matches by chance one time in ten), and when the method is public anyone can make a matching one (task 3). Real systems use hash functions and a keyed checksum called a MAC.
Code: radio.sendValue(name, value) sends text and a number together, so the message and its checksum travel in one packet. The name is limited to 8 characters.
A plain checksum catches accidents but not deliberate changes. Ask what an attacker would need to make a changed message pass.
| What you will see | A question to ask | The fix |
|---|---|---|
| Every message is rejected. | Do the sender and receiver use the same secretKey? | Use one secretKey value on both micro:bits. |
| A name longer than 8 letters is cut short. | How long is the message? | radio.sendValue names are limited to 8 characters. Use shorter messages. |
One possible solution for each task. Other correct programs are fine.

let ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
let secretKey = 7
function checksum(message: string): number {
let total = secretKey
for (let i = 0; i < message.length; i++) {
total += ALPHABET.indexOf(message.charAt(i))
}
return total % 10
}
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
radio.sendValue("HELLO", checksum("HELLO"))
})
input.onButtonPressed(Button.B, function () {
radio.sendValue("HELLP", checksum("HELLO"))
})
radio.onReceivedValue(function (name, value) {
if (checksum(name) == value) {
basic.showString(name)
} else {
basic.showIcon(IconNames.No)
}
})

let ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
let secretKey = 7
let bad = 0
function checksum(message: string): number {
let total = secretKey
for (let i = 0; i < message.length; i++) {
total += ALPHABET.indexOf(message.charAt(i))
}
return total % 10
}
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
radio.sendValue("MEET", checksum("MEET"))
})
input.onButtonPressed(Button.B, function () {
radio.sendValue("MEAT", checksum("MEET"))
})
input.onButtonPressed(Button.AB, function () {
basic.showNumber(bad)
})
radio.onReceivedValue(function (name, value) {
if (checksum(name) == value) {
basic.showIcon(IconNames.Yes)
} else {
bad += 1
basic.showIcon(IconNames.No)
}
})
Stretch: Make the checksum depend on order: add the letter's place times its position in the message.
Support: Give the receiving checker complete and ask students to write only the sender.
What does a checksum let a receiver notice?
That the message was damaged or changed after the checksum was worked out. A keyed checksum also stops someone making a matching one without the key.
Next: prove who is sending, not just that the message is whole.