Having fun with reverse vending machines

I have a bad habit of breaking things on purpose, just to see what would happen if I do.
And in this case, I was recycling some bottles a few weeks ago, and I happened to take a quick look at the EAN code on the receipts that I got from the machine.

receipt1

From the pictures we can immediately come to two conclusions

1: The 7 digits (read from left to right) are probably the same on all the receipts from the same machine.

2: The third digit (read from right to left) is the amount of money on the receipt

Now, these receipts are usually given to the cashier.
When given to the cashier, she/he scans them and makes sure that they’re valid and then proceeds to give you the money or takes the money off from your purchase.
The cashier then draws a line over the EAN codes of the receipts and keeps them, so that it can’t be used again.

From that behavior, and from what we saw before on the receipts, we can draw another conclusion

3: The receipt is not unique, and could be scanned as many times as we want (We could make copies of it for example)

The receipts seem to vary a bit between machines/stores (gonna check if I can find some more info on that).
But for now I’ll focus on the Tomra T-83 HCpIII that this store has.

Tomra T-83 HCp website
Tomra T-83 HCp PDF

tomra-t-83hcp_p1

Now, if you create fake receipts with a normal printer, it would probably be discovered by the cashier, since the receipts use a special kind of paper and ink.
Although those printers + paper aren’t very hard to come by, so that wouldn’t be too hard to solve.

Epson TM-T88IV

tmt88iv

But, let’s put that aside and assume that you can’t go via the cashier (My goal here is not to create fake receipts and earn a bunch of money, so going via the cashier and getting cash would be pointless here). In the store where I am conducting these little experiments, there’s a “self checkout” area, where you can draw your membership card, scan everything yourself and then pay with a credit or debit card (They have random checks at times to make sure that people aren’t cheating). Next to the machine where you scan the EAN codes of the products that you are buying, there’s a small machine where you can put in different notes (with EAN codes) with offers on (buy 2 get 70% of on the third blabla etc), but you can also put in your receipts there and it will scan it, verify it and then draw the amount of your purchase.

A few things that should be noted here are;

4: The paper with the different offers and the recycling receipts, are on different kind of papers with different ink and quality, which makes me think that there aren’t many (if any) restrictions on the size and quality of the paper and EAN code, as long as it’s readable. Thus, even if I wanted to print it on normal A4 paper that I have in my printer at home, it would probably work.

5: The company that makes this EAN code reader is not the same one that makes the reverse vending machine for recycling the cans.

6: When the paper is inserted into the EAN code reader, if the EAN is valid, the machine keeps the paper. This further confirms point 3 that the code could probably be scanned several times if we wanted (which makes me think of a few fun things we could do with those “Weekly offers” papers that we get sometimes when shopping there, but that’s for another blog entry).

Now that we know all this, we need to do a few things!

* We need to analyze the receipts and figure out what the numbers are (to make templates later)

* We need to gather info on the machines that are used in this experiment (EAN barcode printers and scanners)

* Write a program that can generate these receipts from a template (Might as well do it while I’m at it)

So these are the two receipts that I have right now

Store: ICA Kvantum (Malmborgs Mobilia Malmö)
Machine: Tomra T-83 HCpIII
EAN Code: 9 999900 000702

Store: ICA Kvantum (Malmborgs Mobilia Malmö)
Machine: Tomra T-83 HCpIII
EAN Code: 9 999900 001006

These receipts use the EAN-13 standard, and since we already concluded that the first part of the code is the same on all these receipts,
we’ll just focus on the last part of the code, the 001006 and 000702.
According to the EAN-13 standard, the last digit is always the “check digit” or “checksum”, which is calculated like this:

References:
http://en.wikipedia.org/wiki/ISBN#ISBN-13_check_digit_calculation
http://en.wikipedia.org/wiki/EAN-13

9*1 + 9*3 + 9*1 + 9*3 + 9*1 + 0*3 + 0*1 + 0*3 + 0*1 + 0*3 + 7*1 + 0*3
=
9 + 27 + 9 + 27 + 9 + 7 = 88
=>
88/10 = 8,8
(take the rest)
10 - 8 = 2
The check digit is 2

So now that we know what the check digit is and how to calculate it, let’s focus on the rest of the numbers that we have left, which is the 001006 and 000702.
If we remove the check digit, we have this

00100
00070

And since we had one receipt on 10 SEK and one with 7 SEK, this one is pretty easy to guess, that on the first one, the “10” part is the 10 SEK, and on the second one the “7” is the 7 SEK.
So from this we can conclude that reading it from left to right, we have a digit for thousand, hundred, ten, ones and a decimal (Under 1 SEK is öre, but we don’t have that as a part of our currency any longer in Sweden, so I’ll just call it decimal for now).

So now that we know all this, we can actually create a fake receipt with just about any value we want (that fits in the EAN code of course).
To try this out and see how close to the original we can get without just putting a receipt in a machine and making copies, I have created a template in LaTex where one can just insert the right values in the template, and then convert it to a picture or PDF and print it to get the finished receipt.
The template can be seen below.

Template in LaTeX:

documentclass[12pt]{article}
usepackage{lmodern}
usepackage[utf8]{inputenc}
usepackage[paperwidth=57mm,paperheight=113mm,margin=3mm]{geometry}
%usepackage{geometry}
usepackage{graphicx}
usepackage{setspace}
usepackage{color}
%usepackage{ean13}
usepackage{soul}
geometry{verbose}
makeatletter

title{ICA Kvantum T-83HCp Receipt Template}
date{today}
makeatother

begin{document}
%begin{minipage}[t]{57mm}
centering{includegraphics{STORE_LOGO_IMG}}
pagecolor{white}
vspace{1mm}

textsf{textbf{Large TITLE_PART_1}}textsf{Large {} }
{Large {} {} {} }textsf{Large {} }textsf{textbf{Large TITLE_PART_2}}{Large }

%Large space between title and total
vspace{20mm}

%Total amount of money
centering
colorbox{black}{hspace{linewidth}hspace{HSPACEfboxsep}color{white}textbf{Large TOTAL_MONEY}{Large }}{Large par}

%Tiny space between total and ean
vspace{1mm}
centering
%EAN image
includegraphics{EAN_IMG}

%Space plus ean numbers under ean
begin{spacing}{0.5}
textsf{textbf{textsc{small EAN_NUM}}}{small par}
end{spacing}

%Space between ean and bottle/can amount
vspace{4mm}

%Amount of bottles/cans
textsf{textbf{footnotesize COUNT_BOTTLE flaskor/burkar áhfill{}AMOUNT_PER_BOTTLE}}{footnotesize par}
textsf{textbf{footnotesize rule[0.5ex]{1columnwidth}{1pt}}}{footnotesize par}

begin{spacing}{0.8}
textsf{textbf{footnotesize MODEL_NAME}}{footnotesize par}
textsf{textbf{footnotesize SERIAL_NUMBER}}{footnotesize par}
textsf{textbf{footnotesize TIME DATE}}
end{spacing}
%end{minipage}
end{document}

Generator script:

gen.sh (For safety reasons, the barcode script is not included)

#!/bin/bash

# This is a generator script for the ICA Malmborgs template
# I have left out some important parts, to protect the store in question
# Usage:
# bash gen.sh total_money

# Copy template to a temporary location
cp receipt.tex /tmp/receipt.tmp.tex

#Set path, bar width and height
path="EAN_IMG.png"
barwidth=1
barheight=60

# Set the numbers for the EAN
first=9
left=999900
right=$(bash right.sh $1)

# Decide the control digit
control=$(bash control.sh $first $left $right)
echo $control

# Set hspace (it needs to differe depending on the input value)
hspace=$(bash hspace.sh $1)

# Create the barcode here named EAN_IMG.png
# You will have to figure out for yourself how to do that though
# And write the barcode script yourself
# <insert barcode call here>

# Get time and date values
time_var=$(date +%H:%M)
date_var=$(date +%d-$(echo $(date +%b) | tr '[:lower:]' '[:upper:]')-%Y)

# Replace placeholders in template
sed -i 's/STORE_LOGO_IMG/STORE_LOGO_IMG.jpg/g' /tmp/receipt.tmp.tex
sed -i 's/TITLE_PART_1/Malmborgs/g' /tmp/receipt.tmp.tex
sed -i 's/TITLE_PART_2/Mobilia/g' /tmp/receipt.tmp.tex
sed -i "s/HSPACE/$hspace/g" /tmp/receipt.tmp.tex
sed -i "s/TOTAL_MONEY/$1.00/g" /tmp/receipt.tmp.tex
sed -i 's/EAN_IMG/EAN_IMG.png/g' /tmp/receipt.tmp.tex
sed -i "s/EAN_NUM/$first \hspace{1mm} \so{$left} \hspace{1mm} \so{$right$control}/g" /tmp/receipt.tmp.tex
sed -i 's/COUNT_BOTTLE/7/g' /tmp/receipt.tmp.tex
sed -i 's/AMOUNT_PER_BOTTLE/1.00/g' /tmp/receipt.tmp.tex
sed -i 's/MODEL_NAME/Tomra 83 HCp3/g' /tmp/receipt.tmp.tex
sed -i 's/SERIAL_NUMBER/606657-90199310-01456-00/g' /tmp/receipt.tmp.tex
sed -i "s/TIME/$time_var/g" /tmp/receipt.tmp.tex
sed -i "s/DATE/$date_var/g" /tmp/receipt.tmp.tex

# Create PDF and PNG
pdflatex /tmp/receipt.tmp.tex receipt.tmp.pdf
convert receipt.tmp.pdf receipt.png

# remove temp files
rm /tmp/receipt.tmp.tex
rm EAN_IMG.png

 

hspace.sh – This one sets the hspace value (template design related)

#!/bin/bash

val=$1
hspace="-12"

#There's probably a better way to do this
if  [[ ${#val} = 1 ]] ; then
   hspace="-12"
elif  [[ ${#val} = 2 ]] ; then
   hspace="-15"
elif [[ ${#val} = 3 ]] ; then
   hspace="-20"
elif [[ ${#val} = 4 ]] ; then
   hspace="-25"
fi

echo $hspace

 

control.sh – This one calculates the control digit

#!/bin/bash

var=$1$2$3
echo $var
vartwo=0

for i in {0..11}
do
    tmp=${var:$i:1}

    if [ $(($(($i+1))%2)) -eq 0 ] ; then
        vartwo=$(($vartwo+$(($tmp*3))))
    else
        vartwo=$(($vartwo+$(($tmp*1))))
    fi
done

vartwo=$(($vartwo%10))
vartwo=$((10-$vartwo))
echo $vartwo

 

right.sh – This one calculates the right part of the EAN number

#!/bin/bash

val=$1
right=0

#There's probably a better way to do this
if  [[ ${#val} = 1 ]] ; then
   right="000${val}0"
elif  [[ ${#val} = 2 ]] ; then
   right="00${val}0"
elif [[ ${#val} = 3 ]] ; then
   right="0${val}0"
elif [[ ${#val} = 4 ]] ; then
   right="${val}0"
fi

echo $right

 

Usage:
The easiest way to use it would be to simply run the gen.sh script. As it is right now the script will probably fail, since the pictures are missing, which I will not provide right now. But when it works, it will output a pdf and a png with the receipt. An easier way to generate them will be made together with a colleague of mine, although this will probably not be release to the public, and only presented to the company that I have targeted in this little research.

bash gen.sh sek

 

Requirements

The soul LaTeX package
The lmodern fonts for LaTeX

Result:

The EAN code has been made a bit smaller now so that it can’t be scanned in the stores.
receipt

This concludes my research for now on this topic.
I have a solution for this problem that I will write about in another post later.

Click HERE for part 2

7 thoughts on “Having fun with reverse vending machines

  1. So, it all boils down to this being security by obscurity: buy the right receipt printer, the right paper, and you can live a comfortable life.

    Like

  2. Pingback: Confronting the store about the problem | Alcor

  3. Maybe it would be easer to copy EAN of existing cheque, change amount and check number value and generate with free EAN-13 barcode generator and then print it?

    Like

    • Yeah that would be one way to do it, but the journey was the fun part for me. So writing the code to make a “perfect” copy which then printed with the correct paper and size, felt like a great achievement : )

      Like

      • You’re really talented, I enjoyed reading this article, did you study programming at university or something?

        Like

      • Thank you! I’m happy you enjoyed it. I studied Software Engineering at “Blekinge Institute of Technology” in Sweden 🙂

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.