Andy Crouch - Code, Technology & Obfuscation ...

Validating MPAN Numbers

Photo: Tim Mossholder - Unsplash

This week I wanted to cover an energy domain specific problem and solution. The approach I took use’s one of my favourite .Net features, Extension Methods.

The problem is simple, validating an MPAN number.

Whoa, what is an MPAN number you ask? An MPAN number is a Meter Point Administration Number. It is the identifier used to label electricity meters in the UK. They are also sometimes called Supply Numbers or S-Numbers. There is an equivalent for Gas Meters. These are generally known as MPRN or Meter Point Reference Numbers.

The MPAN numbers comprise different elements relating to the supply. These include the Profile Type, Meter Time-Switch Code, Line Loss Factor and the Core Identifier. As it turns out you can validate legitimate MPAN numbers. This is achieved by generating a checksum from 12 of the Core Identifier digits. You then compare it to a check digit which is the final digit of the MPAN.

The checksum is calculated as follows:

  • Extract the final 13 digits from the MPAN which is the Core Identifier.
  • Remove the final digit for use later. This is the check digit which is used to validate the MPAN.
  • Using the remaining 12 digits, start by multiplying the first digit by 3.
  • Multiply the second digit by the next prime number, 5.
  • Repeat this process for each remaining ten digits. But, miss 11 out on the list of prime numbers used to create the digit sums.
  • Calculate a checksum by summing up all these products.
  • Generate a check digit by using the checksum modulo 11 modulo 10.

The calculated check digit is compared to the last digit of the MPAN. If they match then you have a valid MPAN number.

There are solutions floating around the internet for this in many languages. It was a task that one of our more junior developers was attacking to ensure we had a single MPAN validator. It reminded me of a typical interview question or Friday fun team task and so opened it to the team. The only criteria were that it could take no longer than half an hour to code up. Below is my example MPANValidationExtensions class. It contains two simple methods, IsValidMPAN(meterIdentifier) and IsNotValidMPAN(meterIdentifier).

using System;
using System.Collections.Generic;
using System.Linq;

namespace MPANValidatior
{
    public static class MPANValidationExtensions
    {
        public static bool IsValidMPAN(this string meterIdentifier)
        {
            const int MPAN_LENGTH = 13;
            
            if (meterIdentifier == null || meterIdentifier.Length != MPAN_LENGTH)
            return false;
            
            var primeNumbers = new List<int>() { 3, 5, 7, 13, 17, 19, 23, 29, 31, 37, 41, 43 };
            List<int> digitCheckSumResults = new List<int>();
            
            int primeNumberIdx = 0;
            meterIdentifier
            .Substring(0, MPAN_LENGTH - 1)
            .ToCharArray()
            .Where(x => int.TryParse(x.ToString(), out int convertedInt))
            .Select(x => Convert.ToInt16(x.ToString()))
            .ToList()
            .ForEach(x => digitCheckSumResults.Add(x * primeNumbers[primeNumberIdx++]));
            
            var checkDigit = Convert.ToUInt16(meterIdentifier.Substring(MPAN_LENGTH - 1, 1));
            
            return checkDigit == (digitCheckSumResults.Sum() % 11 % 10);
        }
        
        public static bool IsNotValidMPAN(this string meterIdentifier)
        {
            return !IsValidMPAN(meterIdentifier);
        }
    }
}

(Always provide a negated version of a boolean Extension method. It really does improve readability.)

This is a fast, simple solution. It processes around 3000 MPANs in around 68 milliseconds. It is also provided as a string Extension. There is no need to instigate objects to provide this utility functionality. Include the namespace and just use where needed.

If you have questions around validating MPAN numbers or alternative solutions then contact me via twitter or email.