How Do I Validate An Australian Medicare Number?
Solution 1:
The regex supplied by Jeffrey Kemp (March 11) would help to validate the allowed characters, but the check algorithm below should be enough to validate that the number conforms to Medicare's rules.
The Medicare card number comprises:
- Eight digits;
- A check digit (one digit); and
- An issue number (one digit).
Note: the first digit of the Medicare card number should be in the range 2 to 6.
Medicare card number check digit calculation
- Calculate the sum of: ((digit 1) + (digit 2 * 3) + (digit 3 * 7) + (digit 4 * 9) + (digit 5) + (digit 6 * 3) + (digit 7 * 7) + (digit 8 * 9))
where digit 1 is the highest place value digit of the Medicare card number and digit 8 is the lowest place value digit of the Medicare card number.
Example: for Medicare card number '2123 45670 1', digit 1 is 2 and digit 8 is 7.
- Divide the calculated sum by 10.
- The check digit is the remainder.
Example: For Medicare card number 2123 4567.
- (2) + (1 * 3) + (2 * 7) + (3 * 9) + (4) + (5 * 3) + (6 * 7) + (7 * 9) = 170
- Divide 170 by 10. The remainder is 0.
- The check digit for this Medicare number is 0.
Source: "Use of Healthcare Identifiers in Health Software Systems - Software Conformance Requirements, Version 1.4", NEHTA, 3/05/2011
Solution 2:
If you are looking for a C# version, give this a try:
using System.Linq;
//...publicboolIsMedicareFormatValid(string medicareNumber)
{
if (!(medicareNumber?.Length >= 10 && medicareNumber.Length <12) || !medicareNumber.All(char.IsDigit))
returnfalse;
var digits = medicareNumber.Select(c => (int) char.GetNumericValue(c)).ToArray();
return digits[8] == GetMedicareChecksum(digits.Take(8).ToArray());
}
privateintGetMedicareChecksum(int[] digits)
{
return digits.Zip(new[] { 1, 3, 7, 9, 1, 3, 7, 9 }, (m, d) => m*d).Sum() % 10;
}
Note: This will return false for null values, you might want to throw an exception.
To clarify:
- The first 9 Numbers in the medicare card would correspond to the actual medicare number (used in the check).
- The 9th digit is a check digit calculated in the
GetMedicareChecksum
method. - The 10th digit identifies the number of the card, so if you've been issued 3 cards (because you've lost it or whatever), the number would be 3
- The 11th digit would identify the family member inside the group.
Hope someone finds this useful.
Solution 3:
Here's a Typescript or modern Javascript solution:
validateMedicare(medicare) {
let isValid = false;
if (medicare && medicare.length === 10) {
const matches = medicare.match(/^(\d{8})(\d)/);
if (!matches) {
return { invalid: true };
}
const base = matches[1];
const checkDigit = matches[2];
const weights = [1, 3, 7, 9, 1, 3, 7, 9];
let sum = 0;
for (let i = 0; i < weights.length; i++) {
sum += parseInt(base[i], 10) * weights[i];
}
isValid = sum % 10 === parseInt(checkDigit, 10);
}
return isValid;
}
Please refer to http://clearwater.com.au/code/medicare for an explanation.
To test, generate medicare number here: https://precedencehealthcare.com/rmig/
Solution 4:
Added Swift version
classfuncisMedicareValid(input : String, validateWithIrn : Bool) -> Bool {
let multipliers = [1, 3, 7, 9, 1, 3, 7, 9]
let pattern ="^(\\d{8})(\\d)"let medicareNumber = input.removeWhitespace()
let length = validateWithIrn ?11 : 10if medicareNumber.characters.count != length {returnfalse}
let expression =try!NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions.CaseInsensitive)
let matches = expression.matchesInString(medicareNumber, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0, length))
if (matches.count >0&& matches[0].numberOfRanges >2) {
let base = medicareNumber.substringWithRange(medicareNumber.startIndex...medicareNumber.startIndex.advancedBy(matches[0].rangeAtIndex(1).length))
let checkDigitStartIndex = medicareNumber.startIndex.advancedBy(matches[0].rangeAtIndex(2).location )
let checkDigitEndIndex = checkDigitStartIndex.advancedBy(matches[0].rangeAtIndex(2).length)
let checkDigit = medicareNumber.substringWithRange(checkDigitStartIndex..<checkDigitEndIndex)
var total =0for i in0..<multipliers.count {
total +=Int(base.charAtIndex(i))!* multipliers[i]
}
return (total %10) ==Int(checkDigit)
}
returnfalse
}
I use some String extensions as well to simplify some operations.
extensionString {
funccharAtIndex (index: Int) -> String{
var character =""if (index <self.characters.count){
let locationStart =self.startIndex.advancedBy(index)
let locationEnd =self.startIndex.advancedBy(index +1 )
character =self.substringWithRange(locationStart..<locationEnd)
}
return character
}
funcreplace(string:String, replacement:String) -> String {
returnself.stringByReplacingOccurrencesOfString(string, withString: replacement, options: NSStringCompareOptions.LiteralSearch, range: nil)
}
funcremoveWhitespace() -> String {
returnself.replace(" ", replacement: "")
}
}
Solution 5:
Added Java Version
publicstaticbooleanisMedicareValid(String input, boolean validateWithIRN){
int[] multipliers = newint[]{1, 3, 7, 9, 1, 3, 7, 9};
Stringpattern="^(\\d{8})(\\d)";
StringmedicareNumber= input.replace(" " , "");
intlength= validateWithIRN ? 11 : 10;
if (medicareNumber.length() != length) {returnfalse;}
PatternmedicatePattern= Pattern.compile(pattern);
Matchermatcher= medicatePattern.matcher(medicareNumber);
if (matcher.find()){
Stringbase= matcher.group(1);
StringcheckDigit= matcher.group(2);
inttotal=0;
for (inti=0; i < multipliers.length; i++){
total += base.charAt(i) * multipliers[i];
}
return ((total % 10) == Integer.parseInt(checkDigit));
}
returnfalse;
}
Post a Comment for "How Do I Validate An Australian Medicare Number?"