# Checking validity of NHS numbers

**URL:** <https://www.ruby-forum.com/t/checking-validity-of-nhs-numbers/92369>\
**Category:** Rails\
**Created:** [April 18, 2007, 7:15pm UTC](https://www.ruby-forum.com/t/checking-validity-of-nhs-numbers/92369 "2007-04-18T19:15:43Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ratcheer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/aca169/32.png) [@ratcheer](https://www.ruby-forum.com/u/ratcheer)\
**Post date:** [April 18, 2007, 7:15pm UTC](https://www.ruby-forum.com/t/checking-validity-of-nhs-numbers/92369/1 "2007-04-18T19:15:43Z")

</div>

Hello

I need to check that the NHS numbers in my database are valid. I’m  
storing them as ten-digit strings: the first nine are the identifier and  
the tenth is a check digit.

There are four steps to calculating the check digit (from  
[UK Government Web Archive](http://www.connectingforhealth.nhs.uk/systemsandservices/nsts/docs/tech_nn_check_digit.pdf)):

1. multiply each of the first nine digits by a weighting factor (10 for  
the first digit, 9 for the second… 2 for the ninth)

2. sum the results of these multiplications

3. divide the total by 11 and establish the remainder

4. subtract the remainder from 11 to give the check digit.

If the result of step 4 is 11 a check digit of 0 is used; if the result  
is 10 then the number is invalid.

I’m struggling to implement this into my model. I imagine that the first  
thing is to convert the string to an array:

nhs\_no = “1234567890”  
nhs\_no.split(“”).map{ |v| v.to\_i } # =\> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

Then I get a bit stuck (i.e. before step 1!): I want to transform the  
first nine digits of the array so that the new value of the kth element  
is v\*(10-k).

I hope this makes some sense, and I’d really appreciate any help.

Thanks.

---

<div class="post-metadata">

**Author:** ![ratcheer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/aca169/32.png) [@ratcheer](https://www.ruby-forum.com/u/ratcheer)\
**Post date:** [April 18, 2007, 7:24pm UTC](https://www.ruby-forum.com/t/checking-validity-of-nhs-numbers/92369/2 "2007-04-18T19:24:41Z")

</div>

On Apr 18, 2007, at 1:15 PM, Tim C. wrote:

> tech\_nn\_check\_digit.pdf):
> 
> 9, 0]
> 
> Then I get a bit stuck (i.e. before step 1!): I want to transform the  
> first nine digits of the array so that the new value of the kth  
> element  
> is v\*(10-k).

You probably want the Enumerable#each\_with\_index method, eg.

new\_array = []  
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0].each\_with\_index do |value, index|  
new\_array.push(value \* (10 - index))  
end

James.

–  
James S.  
Play: [http://james.anthropiccollective.org](http://james.anthropiccollective.org)  
Work: [http://jystewart.net/process/](http://jystewart.net/process/)

---

<div class="post-metadata">

**Author:** ![ratcheer](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/aca169/32.png) [@ratcheer](https://www.ruby-forum.com/u/ratcheer)\
**Post date:** [April 19, 2007, 1:11pm UTC](https://www.ruby-forum.com/t/checking-validity-of-nhs-numbers/92369/3 "2007-04-19T13:11:35Z")

</div>

James S. wrote:

> You probably want the Enumerable#each\_with\_index method, eg.
> 
> new\_array = []  
> [1, 2, 3, 4, 5, 6, 7, 8, 9, 0].each\_with\_index do |value, index|  
> new\_array.push(value \* (10 - index))  
> end

Thank you James! In case anyone’s interested here’s a function which  
returns the check digit for a given NHS number string:

def check\_digit(nhs\_number)  
# must be ten digits long  
unless nhs\_number.length == 10  
check\_digit = nil  
else  
new\_array = []  
nhs\_number.split("").map{ |v| v.to\_i }.each\_with\_index do |value,  
index|  
new\_array.push(value \* (10 - index)) if index \< 9  
end  
check\_digit = 11-new\_array.sum.remainder(11)  
# recode check digit of 11 to 0 and ‘disallow’ 10  
case check\_digit  
when 11 then check\_digit = 0  
when 10 then check\_digit = nil  
end  
# disallow NHS numbers like “1111111111”, “2222222222” etc.  
check\_digit = nil if check\_digit.to\_s\*10 == nhs\_number  
end  
check\_digit  
end

I’m sure that I could make this more elegant somehow, especially if  
there were a ‘map\_with\_index’ function…
