As you can see here a check digit according to check digit procedure ISO7064 MOD 11,10 has to be attached to blood bag numbers prior to delivery as haemotherapeutic drug. In Croatia the same check digit is used as a personal identification number (also known as OIB). Some hybrid systems based on the same standard are also used in banks and probably on many other places for various purposes.
There is nothing special in this algorithm, but today I found a blog post by Domagoj Pavlešić where he has provided OIB check validity algorithm written is several programming languages (he even wrote a web service which can be used for free). Although there is nothing wrong with his algorithms, I decided to write my own version of the algorithm because I didn't like his C# version (it's is too long) and because F# version was missing (I love F#) :)
First the C# version which is shorter because Enumerable.Aggregate method is used instead of for loop:
private static bool CheckOib(string oib)
{
if (oib.Length != 11) return false;
long oibL;
int[] digits;
if (long.TryParse(oib, out oibL))
digits = Array.ConvertAll(oib.ToCharArray(), c => Int32.Parse(c.ToString()));
else return false;
return digits[10] ==
11 - digits.Take(10)
.Aggregate(10, (x1, x2) => ((x1 + x2) % 10 == 0 ? 10 : (x1 + x2) % 10) * 2 % 11);
}
And then the F# version:
open System
let modulo10 x1 x2 = if (x1 + x2) % 10 = 0 then 10 else (x1 + x2) % 10
let digits s = s |> Seq.map(string >> int) |> Seq.to_list |> List.rev
let CheckOib (x:String) =
if x.Length <> 11 then false
else
let succ, value = Int64.TryParse(x)
if succ then
let l = digits x
l.Head = 11 - (l.Tail |> List.fold(fun x1 x2 -> (modulo10 x1 x2) * 2 % 11) 10)
else
false
Console.WriteLine(CheckOib "your_oib")