Skip to content

Instantly share code, notes, and snippets.

@lionello
Last active September 7, 2017 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lionello/60cd2f1524c664d4d8454c01a05ac2c8 to your computer and use it in GitHub Desktop.
Save lionello/60cd2f1524c664d4d8454c01a05ac2c8 to your computer and use it in GitHub Desktop.
MRZ (Machine Readable Zone) checksum calculator
// Copyright Lionello Lunesu, placed in the public domain.
import std.algorithm;
import std.range;
ubyte charCode(dchar c) pure {
switch (c) {
case '<': return 0;
case 'A': .. case 'Z': return cast(ubyte)(c - 'A' + 10);
case '0': .. case '9': return cast(ubyte)(c - '0');
default: assert(0);
}
}
static assert(charCode('Z') == 35);
static assert(charCode('9') == 9);
int calcMrz(string data) pure {
return data
.map!(charCode)
.zip([7,3,1].cycle)
.fold!( (a,b) => a + b[0]*b[1] )(0) % 10;
}
static assert(calcMrz("AB2134<<<") == 5);
string calcField(string data) pure {
return data ~ cast(char)('0' + calcMrz(data));
}
static assert(calcField("140910") == "1409105");
void main(string[] args) {
import std.stdio;
writeln(args[1..$]
.map!(calcField)
.fold!( (a,b) => a~b )
.calcField
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment