Week 2

Last week we had been told, on the Friday before, that "This means that the contract pack should be with your solicitor early next week." and I wondered why it took as long as it did (given that everyone wants this sorted quickly).

By Tuesday my solicitors were chasing as they won't start the searches until they get the contract pack, it seems.

Finally, Thursday, nearly a week later, the contract pack gets to my solicitors! Naturally I was assuming that this had gone by post for some historic reason, but no, that is not the case. It is all emailed scans, and was not sent until 4:30pm on Thursday.

It is not as if it has much in it, nothing that would, or should, not have been ready to go. It is copy of warranty on some building work, of planning permission, title plan, etc. Much of it I already had as I had spent £3 on the land registry site before even making the offer. This is all stuff I will certainly have ready and scanned as soon as I put my house on the market - why would you not?

Naturally my solicitor was on the case, and getting searches ordered right away, good.

But then on Friday we finally get the fittings and fixtures details. Again, this would be something I expect to be ready when you put the house on the market. Sadly there were a few missed check boxes so my solicitor has to ask for clarification. WHY?!?!

Just to be clear, all of this could have been ready, and with my solicitor, on day 1, as soon as we accepted the offer and they filled in the amount on the contract. That is all that should have been necessary. We are two weeks in to this because of delays by the sellers, when they claim to want to move quickly!

What is slightly annoying it that when we viewed the property the agent was clear that the hot tub, and the bed in the master bedroom, were "negotiable", i.e. they could be left. Both were things that are a pain to move out but have some value. So when we upped our offer to the asking price we said they had to be included, and that was accepted.

What we did not know, not until this fixtures and fittings sheet came through, was that the rather nice light fitting over the stairs, was also negotiable. Had we known, leaving it would have been part of that offer and I am sure that would be accepted seeing as we had gone up to the asking price! Now it is yet another query to be resolved.

I believe at this point we have to wait for searches to complete. As such I am expecting very little over the next week, sadly.

P.S. That light fitting is not that expensive, but the hassle is fitting one over the stairs.


Week 1

It is a week since our offer was accepted...

  • Formal memorandum of sale was sent by agents (with wrong date on it)
  • My solicitors only just asked for money for searches
  • Apparently the "contact pack" is on its way to my solicitor
  • Bugger all else has happened

When making my breakfast I consider the critical path. I put water in the coffee machine and turn it on, even before putting ground coffee in, as the coffee heating and filtering is the longest path in the whole process. I do things in an order that is efficient, where I can, especially if it is something I do a lot.

Now, my understand is that the searches are the time critical aspect here, so one has to wonder why wait a whole week before considering starting them.

Oh well. Let's see how this week goes.


Moving house

I have lived in Bracknell over half my life (so far), so moving house is a bit of a distant memory.

But I believe some people were confused by my previous blog, so worth just clarifying:-

  • I live in Bracknell now - nice house, some customisation (electric locks, etc).
  • I am purchasing a place in Wales, hopefully all sorted by end of this year.
  • Then I will be selling my house in Bracknell, after decorator comes in :-)

I can do this partly due to things like mortgage reserve accounts (if you have one, keep it, do not let the bank try and sneak it away as they tried with me, and with friends of mine). Also I am pretty sure that if you are buying a house in Wales you are officially allowed to just put it on your Amex card (basically downsizing in price by a good chunk). You'd think this would help.

I am amazed at the time scales, really. There are "searches". OK, but have you seen how fast google can do a search. This is not the 18th century!

  • Why is this not all on-line with all councils, etc?
  • Why, if they are all different, is there not a nationwide aggregator that makes it simple?
  • Why is it that, apparently, solicitors tend to do one search after the other, and not all at once?
  • Why is anything time consuming not done as part of putting the house on the market?

Whilst joking about my Amex card (no, I don't have a limit this high), if you have the money ready and sat in an account why does it have to even take "all day" to buy a house. If it was a mandatory two week cooling off period, I could understand, but it sounds like it is just bad management of the process at every level somehow.

So yes, expect more exasperated blogs on the matter.

Also, how is it that technology knows? I have some ES8000 locks - very nice - very reliable. Both of them started playing up and one has given up the ghost, the very day I get confirmation we are moving and that their days are numbered. This is too fluky for reason. Was fun taking one apart though.


Geek's house

As you can imagine, my house has some "features" that make it a tad special.

We are looking to move (to Wales of all places). Working from home works very well, and as such it does not matter much where "home" is...

The house we will be selling, probably in January, is a nice 5 bed house in Bracknell. In some ways I am not sure what to do with the "features". To the right buyer they are rather cool and worth it, so I thought I would list on this blog post and get comments.

The plan, sadly, is to "normalise" the house, meaning removing some features. But here goes - what should I try and keep and sell.

  1. Air-con - this stays as it is "normal". Four of the five bedrooms have air-con, and so does the man-cave. All the air-con is modern, already updated and replaced once even, wifi connected. Works really well for heating and cooling, and has proper planning permission. I have some nice sensors for temp and so on that work with it - open source code, but works as is.
  2. Playhouse/swings - these stay as also "normal", but it is a nice feature, and kids love it.
  3. IoT light switches - in one bedroom and man-cave and garden, Tasmota flashed. Most work the corresponding light so can stay, but some are blind (no direct powered light, using WiFi/mqtt to control other lights). I suspect they stay but diminished usefulness. A buyer can have all the IoT details to use them if they want.
  4. Fibre and network switches and WiFi. These could go with me, and fibre terminated. Or they could stay - A&A will be happy to run an internet link from A&A office in Bracknell, at cost (a few hundred a month) even if NAT, but could have a few IPs and some IPv6. If we do nothing, this just gets ceased, which is a shame. I could leave the WiFi APs, or take with me - even an external garden AP.
  5. ESP32 and Galaxy panel and Pi based alarm and door entry system, very cool. Happy to hand over logins, and the code is all open source. But default is we rip it out as not "standard", leaving bare alarm/PIR wiring in place for conventional alarm system install.
  6. Electric locks on the man cave - these would be changed to boring locks with keys. Even the front door has electric release on the lock which would go. Happy to provide the details and some fobs, for the keys (AES using DESFire cards).
  7. Lots of Ubiquiti cameras and recording box. Again, would go with me by default.
  8. Lots of Ethernet wiring - stays.
  9. The man-cave TV will have to stay - a 65" wallpaper LG OLED which is awesome, but hard to transport.
  10. The man cave is awesome, and the benches all fitted, and a bar. That stays.
  11. There are other cool features like nice mains pressure hot-water.
So, if someone is seriously interested, say so, and we can talk. We would sell for a fair price - but would be nice if we did not have to "normalise" some of the stuff and found a geeky buyer that appreciated it. Otherwise, by end of year this all gets "normalised", and sold as "boring".


Using MIFARE Classic in 2020

This is old news to most people, but do not use MIFARE Classic cards, they are not secure.

What was not clear to me is quite how insecure. Reading up on it a little, it sounds like several issues. Something to do with the random number generator being poor, and a nested attack. These apparently allow access very quickly, and there is even a standard command mfoc to crack such cases. By standard command I mean literally apt install mfoc, seriously.

Now, it seems, that modern cards are not quite as vulnerable, but can be cracked with a brute force attack in some way. This really shows why you don't make your own crypto, ever!

As I am doing some work with MIFARE Classic for a client (yes, I said it was insecure), I thought it worth seeing what that means in practice, in 2020. I found a site covering how to set up a hardnested attack, here.

I set up on a Pi, and realised that did not have much oomph. So I tried my very old linux box I normally use, not bad. But I decided to try my iMac. This meant a few brew commands instead of apt commands, but getting the hardnested mfoc compiled was simple.

It was a tad harder to run as the iMac grabs the NFC reader and I had to edit the Info.plist file in recovery mode to remove the ACR122U reader I am using, and compile libnfc with ./configure --with-drivers=acr122_pcsc

However, it then ran. I loaded a card where I had put a key it could not read.

It took nearly 10 minutes to get the key, and after several tests I found that was about the longest it takes, with it often finding in under 3 minutes. It will work through all of the unknown keys, and get you a dump of the card and all the keys.

This means you can read the card, and make a copy, and change it in any way including changing any "value" settings it has. Basically, it is, at that point, no more secure than a memory stick.

So please, do not use MIFARE Classic as if they are secure!

Of course, our card printing stuff at A&A will encode MIFARE Classic for you, but then it also does other insecure systems like mag stripe, and QR codes. MIFARE Classic is fine if you treat it just as a machine readable data store, much like mag stripe or a QR code - it is just not secure.

When it comes to more secure cards like DESFire, we don't encode them but we record which card has what card ID so you can encode them yourself later. This saves us having anyone's keys.

(P.S. I use MIFARE DESFire EV cards with AES for my door entry stuff)


Smart card readers

I have had a very frustrating month with the new card printer and its RFID reader.

The printer itself has been quite fun to reverse engineer, but the smart card readers were not expected to be an issue. The reason is that they are separate (built in) devices that talk USB. Smart card readers are well supported on both linux and windows.

This printer has two such readers, a "contact" station, and a "contactless station" (i.e. RFID).

Oddly, even though there are many readers, including the HID CardMan 5422 which do both in one chipset, the printer actually has two totally separate modules.

The "contact station" worked as expected (apart from needed an adjustment to allow for the gaps around SIMs). Basically, the standard PCSC / winscard stuff just sees the reader, and sees the card, and just works, as expected.

As a result I was able to make the card printing system handle contact cards, SIMs, with ease.

However, from the very start, the contactless / RFID station did not work. It showed up as a Cardman 5121 reader, which was recognised, but showed that the card was inserted already. It did nothing when loading a card on the contactless station.

I was not expecting linux support, but it did not work from Windows. It seems windows recognised the reader and was happy that it has the right drivers for it, and that it should be working. It too just showed the card inserted.

We have had :-

  • Trying on linux, and it not working.
  • Suppliers sending a pcsc test app for windows, which showed it did not work.
  • Suppliers taking well over a week with the printer back with them testing the RFID reader. Confirming it works for them.
  • My retesting, I even sent them a video of testing cards!
  • Suppliers sending some MIFARE cards, in case the cards I was trying were the problem (I tried several different types of RFID card).
  • Finally, suppliers send a new card reader

I was slightly worried about the lack of anti-static packaging, but it did the same, it simply showed the card inserted all the time but no actual data - on windows and linux.


They email saying "here are the drivers you need to install". Well, I am not a windows expert, and it took me a while to convince windows to install the new drivers. It was adamant that it had the right drivers, but eventually I managed it, and bingo it works.

They could have told me it needs "special" drivers a month ago.

I admit, now I know, it did take me around an hour of googling and cursing to get working on linux on a Pi, but I managed it. I tried installing PCSC from source, and all sorts. I tried installing linux drivers from HID, but could only find x64 or i686.

Eventually I found drivers for the 5122 model, which claims to cover the 5121 in the README, and a load of others, and is available in ARM format for a Pi. Yay, it works.

A couple of hours later, and we are now doing RFID encoding as a standard feature on our card printing. Finally. And we had our first order, for some cards with pictures on them and NTAG encoding of a URL for a photo site for a couple (looks like a birthday present). Yay! All working, just hold a phone next to the card and it pops up asking if you want to open the web page.


Ampersands are fun

We have issues with &, but it is still being fun with the confirmation of payee stuff.

People trying to pay us using the name :-


Are told that we are not an exact match, but that we are :-


This is wrong!

We are in fact (on companies house) :-


Why is this an issue?

There are a couple of issues :-

  • It is wrong, but does that really matter?
  • It confuses people trying to pay us, thinking something is wrong.
  • It encourages people to ignore warnings
  • Someone could register ANDREWS ARNOLD LTD, which means the bank are claiming we are in fact a different company.

(Oh look, company 12972728 is ANDREWS ARNOLD LIMITED now)

The real issue?

For me, this is an annoyance which I would really like fixed, but I know mistakes happen. I know all about XML, and ampersands, and protocols, so I do understand.

If the issue is with pay.uk and the confirmation of payee system, then they should fix it. If the issue is the bank, then they should fix it.

What I really really dislike is being lied to, and people making up crap excuses.

Clear this is happening.

I am not happy.

The excuse...

The confirmation of payee system only allows letters and numbers. Special characters like & are replaced with a space.

Well, maybe, but maybe not. It is possible that for matching this happens, but if that is true, then ANDREWS&ARNOLD LTD becomes ANDREWS ARNOLD LTD, which is exactly the trading name reported back as the near match. So if that was true it would be an exact match!

Also, when paying Barclays, we see a near match reported as :-

So clearly Barclays are able to send an &

What needs to happen.

  1. Don't make up excuses or blame other people. That pisses me off.
  2. Fix checking, clearly (however pay.uk passes it on) ANDREWS&ARNOLD LTD should match ANDREWS & ARNOLD LIMITED. So allow it to.
  3. Match LIMITED to LTD (as companies house does) rather than listing a separate trading name with LTD
  4. Send the right name back on a near match, i.e. ANDREWS & ARNOLD LTD

(OK we are changing name from LIMITED to LTD to avoid the trading as crap)


Why A&A are asking you to ask for a PAC?

Update: It looks like we have come to an agreement - way more than I was expecting to pay, but way less than £20k and just on the level of "less hassle than contacting customers". So you won't get an email from A&A about this.

A&A operate some 07 mobile services. These are services that operate an 07 number for incoming and outgoing calls and SMS, and are normally linked to our SIP2SIM service to relay to/from an actual mobile, or diverted to a mobile. The nice thing is that you can be "in the loop" on the mobile calls and texts and handle them in your own systems - e.g. call recording, logging, etc.

What is going to seem odd is that, shortly, we may be emailing all customers of our 07 numbers asking you to log in to the control pages and request a PAC for your number. A PAC allows you to move to a new retail provider.

Why would we do this?

The answer is simple, we have grown increasingly unhappy with the company we used to handle our 07 numbers. We have a new supplier now, who are really responsive and helpful. One of the main issues with the old supplier was how slow they are to answer any queries.

The way mobile services work is that you can get a PAC and change network, simple. For most operators this is a text that returns an instant PAC you can use. Sadly this company do not do that and we have to email, and wait for reply. Given PACs are meant to be issued within a couple of hours this is a tad frustrating. We were promised an API to get PACs years ago (13th April 2017 was "PACs via the API is a couple of weeks away"). The lack of PAC API is one of many annoyances. The new company do PAC via SMS, and that is indeed instant.

So we want to move a lot of our numbers to a new provider. We can't actually move them all, as some cannot be ported (!). These are numbers with no incoming SMS either, which is why we tried to port them. Yes, that is one of the many annoyances, and was pretty much the last straw to be honest. Yes, OFCOM require porting to be agreed, and the new provider are happy to try and sort a Porting contract for those numbers, but OFCOM do not have any time limit on how long that could take. It could take years, apparently, especially with a supplier this slow at answering any queries...

What we need, for the numbers we can port, is a "bulk PAC", a single PAC for the list of several hundred numbers, we then give to the new provider and they all move. Simple.

Unfortunately, the existing supplier want around £20k to cover the admin of issuing this bulk PAC. Not something we ever agreed in our contract. Basically, unless we agree to this, they won't issue the PAC and won't let us move. In my opinion this seems a lot like "blackmail", holding our customers' numbers ransom unless we agree a huge divorce bill which was never agreed in the contract and is clearly unreasonable (no way £20k is an admin fee), though technically probably not legally "blackmail".

I said "we'll just ask our customers to ask for a PAC and use that", to which I was told that would still be a wholesale move and so the fee applies. I said "I'll make a new company, and ask customers to move to that" making it a retail move. No reply, and no reply to several follow up emails (one of the main reasons we want to leave is lack of replies).

So basically, this is what we are doing. Obviously I am ensuring we are 100% technically correct (the best kind of correct), and am making a new company (subsidiary of A&A), and asking customers to move to that retail provider. Once this is sorted we'll seamlessly move customers back to A&A, no problem, but to ensure we are correct and within the OFCOM rules for issuing individual PACs for free for a "retail move", it will be a separate company (who contract for A&A to do billing). I'll even create the inter company billing (net zero) and file accounts for this short lived new company. All above board and proper. Total cost under £50.

Making a new company is cheap and easy (as you can see with company 12972728). I'll go for a more polite name, maybe ((📱)) LTD perhaps.

So the supplier has a choice - the easy way or the hard way. Either hundreds of separate retail PAC requests, each of which needs to be issued within a couple of hours, and for free, or they can issue the bulk PAC we want. I'm even happy to pay a nominal admin fee of £100 or so for the admin work.

Who is it?

Well, I may publish this - it is a small company since taken over by a larger company, but we think this is one individual being "difficult" for no apparent reason.

We'll notify customers with instructions when we do this.

I hope they do opt for the easy way and we don't have to contact customers. We'll do a status post if we do this behind the scenes but it should be seamless.

Reverse engineering

Reverse engineering can be fun - and I usually end up doing it where a supplier does not provide linux based drivers for something.

This is the case with the card printer we use. We have gone through many card printers over the years, including an Evolis pebble, a Zebra, a Matica printer and now a newer Matica printer. Each one lacked any linux drivers. What is also a shame is they did not publish the interface so someone could write some.

This is where regulation could be an interesting option - publishing specs to allow interworking of systems. There is much debate on this, and something for another blog.

However, with some debugging and reverse engineering, I have working drivers for all of the card printers.

Why Matica

The XID9300 and XID8600 are "retransfer" printers - they print on a transfer film, and then transfer to the card. This works really well on SIM cards. The Zebra was too, but did not like cards with gaps or contacts (e.g. around SIM), but the Matica is really good. Retransfer also means proper edge to edge with over the edge bleed on artwork.

Not your typical printer

Usually a printer is write only - you send a print job, it does it, job done. But the card printing is a little specialised. You may want to load a card to a "contact station" (e.g. a SIM) or "contactless (RFID) station", or mag stripe encode or mag stripe read. The way these contact stations work is a pain, but seems pretty industry standard - the printer itself takes a hands-off approach - you tell it to put the card on the station and then talk to something else (over USB) to "encode" the card.

It is also not quite as simple as just sending the print job, even when not encoding a card - you have colour and black, and you want control of each separately (the black is 1 bit per pixel and crisp solid black on top, but the colour is 8 bits per colour). You also have the fact the card has two side, and can even have a UV fluorescent layer. So you need to be able to send "layers" and "sides".

What I wanted was a way to do all of this but over Ethernet from remote systems. We have many systems (like our control pages) from which we need to send card print jobs and encode cards.

I decided to use a TLS over TCP link and send back to back JSON objects each way. It worked well as a system. I also decided that image data to print should be sent as PNG images coded as base64 data URLs in the JSON. This worked surprisingly well, and I have a handle on how the png linux library works now (an annoyingly complex library).

The interface also allows exchange of hex data strings to send to/from a contact or RFID card allowing any "encoding" I wish. This is the key thing that the client does not have to talk to something separate to "encode" cards. It also allows me to hold a job all the way and not have other jobs sneak in whilst trying to encode cards (which happened before).


The previous printer, in this case a Matica XID9300, has Ethernet or USB. I had working drivers from long ago that just did printing, and separately had scripts to talk over USB to the cards. Not ideal.

The new printer is a later model Matica XID8600. This too has Ethernet or USB, but instead of being a setting in a menu it picks one. If USB is connected on power up it is USB. If you want to use Ethernet you must not have USB connected (has an internal USB hub). But if you want to encode cards you have to have USB connected, and if you want to do what we did on the XID9300 (Ethernet print, USB for encoding) you have to unplug USB during power up every time - WTAF?

This was only really apparent after I had written some nice new Ethernet based drivers - a combined system to print over Ethernet and talk to contact stations over USB, all using this TCP TLS JSON connection to the client.


The basic steps are "use the windows drivers" and "observe what is sent to printer". Wireshark is your friend, and I was able to see the Ethernet traffic sent to the printer. There was a nice obvious message structure.

I was really lucky with this printer though as there is a diagnostics tool that the suppliers sent, one they use for maintenance/repair and testing. It has buttons and check boxes for each operation - load a card, move a card, load image data, print images, transfer image to card, etc, etc. And control of all of the settings.

This allowed me to test each operation separately and each option separately and dump the messages. This is absolute slog from a coding point of view - it is spending days trying each separate command and option and looking at hex dumps to work out what each option and setting does in the underlying message. It was tedious.

Once you have that you make test code to generate the same messages and confirm they work, and then build a driver with all of the functions you need.


Whilst I know a lot about Ethernet, I know bugger all about USB. But to avoid the whole "unplug USB during power up" issue, I decided to give it a go.

I was pleased to see that Wireshark comes to the rescue again, and allows dumping of USB traffic on windows. This allowed me to do exactly the same slog of testing each operation and seeing what is exchanged with the printer.

What did I expect?

I expected the XID8600 to be similar to the XID9300, and I was pleased that they were almost the same (Ethernet drivers), but different ports.

The Ethernet has a simple packet/message system - a header with type and length and a variety of commands and parameters. I expected USB to be an alternative way to talk to the underlying printer system and so essentially to be the same with maybe different headers more suitable to USB.

How it works!

I was shocked!

Not even close, not at all, really, crazy. It is like two separate printers! Yes, the underlying operations you can do are the same but the commands and parameters are not remotely related.

Some examples of the craziness.

  • Ethernet has a "transfer" command with an option of where to move the card to after (eject, reject, back to print station, etc), and a flag to say if to flip the card. The flag and "location" code match the card load and card move commands. But on USB there are three separate transfer commands (return, eject, flip) and a flag for "immediate" (no clue what that actually does).
  • Ethernet has a way to get and set some "settings". These are one byte values, and you send a list of tagged values and get back a list of tag/value pairs. To change you send tag/value. So a setting has a "tag" which is a byte, no real logic to which setting is what tag, but I went through each and documented. But USB is not the same, no, not close. You get settings by two separate commands getting blocks of binary data (64 bytes and 14 bytes), and various bytes are various settings, but their position is not related in any way to the tag used in Ethernet. It gets worse, to set these you send two blocks (32 bytes and 10 bytes), where the settings are specific positions (but not related to the ones you fetch). But then if you want to set some settings just for the job, there is a single block of 24 bytes that have most settings, again in different positions.
  • The mag stripe coding messages are similarly different.
  • The film layers have numbers when loading the image data, on the Ethernet they were C, M, Y, K, P, U, but on USB the are K, Y, M, C, U, P, just to be different. When printing the them there is a mask of which to print - for Ethernet it is bit numbers for each layer but always prints C/M/Y together if any set. For USB there is a bit for K, YMC, U, P, instead (so obvious that YMC always together).
(Yes, they persistently use YMCK 👷🤷‍♂️ rather than the more common CMYK, which has led to lots of typos in my code)

Basically, it is like two completely separate specification written independently to meet a list of commands and options. Totally separate logic to how they are coded and the how commands are grouped, and so on.

In addition, the USB used a command structure that seems to be based on USB mass storage, using SCSI commands, or possible mis-using them as Wireshark was not entirely happy with some of them. No idea why they would use that structure, perhaps allowing some standard library to be used from Windows.

The good news

Having coded USB for this I tested on the older XID9300. It works. I was shocked!

Deleting code

This led to a decision to delete and remove all of the Ethernet driver code I wrote. The concept for this project is a Raspberry Pi next to printer acting as a single contact for TCP TLS JSON printing. I have a library for the code to run the client side of this as well. The connection from Pi to printer can be USB with no issue, and indeed is possibly easier than having Ethernet from Pi to printer (needs more config to say IP, etc). So using USB is all that is every required (and marginally faster than Ethernet, oddly).

Deleting code is not something I like doing, but in this case it made the code simpler and made for simpler ongoing maintenance. With both drivers - any changes had to be coded and tested for each way of working.


There are aspects not in the drivers (yet), e.g. we don't have the JIS (Japanese Mag stripe coding) hardware to test that (though easy to code anyway), and we don't have a laminator attachment. So a few bits are not there.

New features

This means we can update our card printing service...

  • 600dpi instead of 300dpi.
  • The UV print no longer has at the MAC address overlay (windows has it but I found the bits to turn it off, yay).
  • We can get the "ID" of an RFID card and store when printing so the API we offer allows you to tie a printed ID to the card ID later for coding - that way we don't need your keys. We even allow the ID to be part of what you print.
  • We plan to offer basic MIFARE classic coding of cards (but really, that is not very secure).
  • We plan to offer MIFARE DESFIRE coding, but means giving us keys.
All in all a good few weeks work on this. I was, however, rather pleased with myself (having spent a day with wireshark) making working USB drivers in a (long) day this weekend.


Fun with QR library

My QR code generation library works well, but one of the features was generating a "colour" QR code. No, QR codes are not normally coloured, the idea is to just show the anatomy of a QR code, which parts are which. Wikipedia does a good job too.

As part of generating the code I have to create the data part, and padding, and then generate the error correction code (ECC) part, and apply various format control bits and fixed black/white units to make the image.

I have updated the library so it will make a QR code which shows what is what. It was a tad complicated by the fact that the error correction code is interleaved. This means that blocks of data and ECC are scrambled so that each block is actually spread out over the QR code. This means you can remove a chunk of the code - e.g. tear off a corner, and that is a small part of several separate blocks. You will notice the padding (green) below is spread out because of this interleaving.

Each block of data and ECC allows recreating of the data from a relatively small part of the overall block, so the distinction between data and ECC is not that relevant. But the colour coding shows how much is used for what quite nicely even so.

This has colour coding for :-

  • Blue: the actual data for the content
  • Green: padding bytes and bits
  • Red: the ECC code
  • Grey: formatting/control
  • Black/White: the fixed pixels in this size QR code

So that is it, just in case you wondered...

(That one above is an NHS COVID-19 QR code).

P.S. I have been having more fun with custom padding bytes. This is not just changing units within the tolerance of the ECC (which can be done, if careful), it is changing padding so that the ECC is still valid.

Of course, if you want to get a bit meta, you can put one type of barcode in the padding of another type. This is a Datamatrix barcode in a QR barcode. A real Frankenstein barcode!

Technically the padding is meant to be a repeating pattern EC/11, and surprisingly this is not just a recommendation in the spec. But obviously nothing checks the padding on read, so allowing pretty padding and hidden data in the padding to work.