Search



Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Sample Java Script for computing Verhoeff's Dihedral Check

The script is presented here as part of an HTML page. The code below can be used by copying all the lines in the above section into an HTML file and opening this with a web browser.

Info

A live version of this web page can be accessed at http://snomed.org/verhoeff.

Code Block
languagejs
<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>SNOMED CT Identifier Check</title>
<style>
body{font-family:Arial, Helvetica, sans-serif}
}
</style>
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type"><meta>
<script type="text/javascript" language="JavaScript">


var FnF = new Array();
FnF[0] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
FnF[1] = [1, 5, 7, 6, 2, 8, 3, 0, 9, 4];
for ( var i = 2; i < 8; i++ )
{
FnF[i] = [,,,,,,,,,];
for ( var j = 0; j < 10; j++ )
FnF[i][j] = FnF[i - 1][FnF[1][j]];
}
var Dihedral = new Array(
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[1, 2, 3, 4, 0, 6, 7, 8, 9, 5],
[2, 3, 4, 0, 1, 7, 8, 9, 5, 6],
[3, 4, 0, 1, 2, 8, 9, 5, 6, 7],
[4, 0, 1, 2, 3, 9, 5, 6, 7, 8],
[5, 9, 8, 7, 6, 0, 4, 3, 2, 1],
[6, 5, 9, 8, 7, 1, 0, 4, 3, 2],
[7, 6, 5, 9, 8, 2, 1, 0, 4, 3],
[8, 7, 6, 5, 9, 3, 2, 1, 0, 4],
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] );
var InverseD5 = new Array(0, 4, 3, 2, 1, 5, 6, 7, 8, 9 );
function VerhoeffCheck()
{
var check = 0;
var IdValue = document.form.numcd.value;
document.getElementById("out").innerText = "";
document.getElementById("out").setAttribute("style", " :red;");
document.getElementById("component").innerText ="Invalid partition";
document.getElementById("component").setAttribute("style", " :green;");
document.getElementById("extnamespace").innerText ="No namespace";
document.getElementById("extnamespace").setAttribute("style", " :red;");
for ( var i=IdValue.length-1; i >=0; i-- )
check = Dihedral[check][FnF[(IdValue.length-i-1) % 8][IdValue.charAt (i)]];
if ( check != 0 ) { document.getElementById("out").innerText = "Check-digit ERROR"; }
else if (IdValue.length < 6) {document.getElementById("out").innerText = "SCTID too short";}
else if (IdValue.length > 18) {document.getElementById("out").innerText = "SCTID too long";}
else {document.getElementById("out").innerText = "Check-digit OK";
document.getElementById("out").setAttribute("style", " :green;");
switch (IdValue.substr(IdValue.length-3,2))
{
case "00":
document.getElementById("component").innerText ="Concept";
document.getElementById("extnamespace").innerText ="International";
break;
case "01":
document.getElementById("component").innerText ="Description";
document.getElementById("extnamespace").innerText ="International";
break;
case "02":
document.getElementById("component").innerText ="Relationship";
document.getElementById("extnamespace").innerText ="International";
break;
case "03":
document.getElementById("component").innerText ="Subset (RF1)";
document.getElementById("extnamespace").innerText ="International";
break;
case "04":
document.getElementById("component").innerText ="Cross Map Set (RF1)";
document.getElementById("extnamespace").innerText ="International";
break;
case "05":
document.getElementById("component").innerText ="Cross Map Target (RF1)";
document.getElementById("extnamespace").innerText ="International";
break;
case "10":
document.getElementById("component").innerText ="Concept";
document.getElementById("extnamespace").innerText =IdValue.substr(IdValue.length-10,7);
break;
case "11":
document.getElementById("component").innerText ="Description";
document.getElementById("extnamespace").innerText =IdValue.substr(IdValue.length-10,7);
break;
case "12":
document.getElementById("component").innerText ="Relationship";
document.getElementById("extnamespace").innerText =IdValue.substr(IdValue.length-10,7);
break;
case "13":
document.getElementById("component").innerText ="Subset (RF1)";
document.getElementById("extnamespace").innerText =IdValue.substr(IdValue.length-10,7);
break;
case "14":
document.getElementById("component").innerText ="Cross Map Set (RF1)";
document.getElementById("extnamespace").innerText =IdValue.substr(IdValue.length-10,7);
break;
case "15":
document.getElementById("component").innerText ="Cross Map Target (RF1)";
document.getElementById("extnamespace").innerText =IdValue.substr(IdValue.length-10,7);
break;
default:
document.getElementById("component").setAttribute("style", " :red;");
}
if (document.getElementById("extnamespace").innerText=='International') {document.getElementById("extnamespace").setAttribute("style", " :green;");}
else if (IdValue.length>10) {document.getElementById("extnamespace").setAttribute("style", " :green;");}
else {document.getElementById("extnamespace").innerText="Invalid Namespace";
}
}
}
function VerhoeffCompute( )
{
var IdValue = document.form.num.value; var check = 0;
document.form.numcd.value= "";
for ( var i = IdValue.length-1; i >=0; i-- )
check = Dihedral[check][FnF[(IdValue.length-i) % 8][IdValue.charAt (i)]];
document.form.numcd.value = document.form.num.value + InverseD5[check];
VerhoeffCheck();
document.getElementById("out").innerText = "Computed check-digit";
}
</script>
</head>
<body>
<h1>SNOMED CT Identifier Check</h1>
<form action="" name="form">
<table border="1" width="441">
<tr>
<td width="212" height="25">
Partial Identifier <br/>(without check-digit) 
</td>
<td width="115" height="25">
<input name="num" size="18"/>
</td>
<td width="92" height="25">
<input onclick= "VerhoeffCompute()" type="button" value="Compute"/>
</td>
</tr>
<tr>
<td width="212" height="35">
SNOMED CT Identifier
</td>
<td width="115" height="35">
<input name="numcd" size="18"/>
</td>
<td width="92" height="35">
<input onclick= "VerhoeffCheck()" type="button" value="Check"/>
</td>
</tr>
<tr>
<td width="212" height="23">
Result of check 
</td>
<td width="115" height="23" colspan="2" id="out">
</td> </tr>
<tr>
<td width="212" height="23">
Component type
</td>
<td width="115" height="23" colspan="2" id="component">
</td> </tr>
<tr>
<td width="212" height="23">
Namespace
</td>
<td width="115" height="23" colspan="2" id="extnamespace">
</td> </tr>
</table>
<p style="margin-left: 0; margin-right: 0">
This Verhoeff checking part of this code was based on a webpage at:
</p>
<ul>
<li>
<a href="http://www.augustana.ab.ca/~mohrj/algorithms/checkdigit.html">
http://www.augustana.ab.ca/~mohrj/algorithms/checkdigit.html
</a>
</li>
</ul>
</form>
</body>
</html>

...

Info

A live version of an HTML form and JavaScript is available in section 5.4.1. SNOMED CT Identifier Check.

Sample Visual Basic for computing Verhoeff's Dihedral Check

Code Block
languagevb
themeEclipse
collapsetrue
Option Explicit
Private Dihedral(9) As Variant
Private FnF(7) As Variant
Private InverseD5 As Variant
Public Function VerhoeffCheck(ByVal IdValue As String) As Boolean
'Check the supplied value and return true or false
Dim tCheck As Integer, i As Integer
VerhoeffArrayInit
For i = Len(IdValue) To 1 Step -1
tCheck = Dihedral(tCheck)(FnF((Len(IdValue) - i) Mod 8)(Val(Mid(IdValue, i, 1))))
Next
VerhoeffCheck = tCheck = 0
End Function
Public Function VerhoeffCompute(ByVal IdValue As String) As String
'Compute the check digit and return the identifier complete with check-digit
Dim tCheck As Integer, i As Integer
VerhoeffArrayInit
For i = Len(IdValue) To 1 Step -1
tCheck = Dihedral(tCheck)(FnF((Len(IdValue) - i + 1) Mod 8)(Val(Mid(IdValue, i, 1))))
Next
VerhoeffCompute = IdValue & InverseD5(tCheck)
End Function
Private Sub VerhoeffArrayInit()
'Create the arrays required
Dim i As Integer, j As Integer
'if already created exit here
If VarType(InverseD5) >= vbArray Then Exit Sub
'create the DihedralD5 array
Dihedral(0) = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Dihedral(1) = Array(1, 2, 3, 4, 0, 6, 7, 8, 9, 5)
Dihedral(2) = Array(2, 3, 4, 0, 1, 7, 8, 9, 5, 6)
Dihedral(3) = Array(3, 4, 0, 1, 2, 8, 9, 5, 6, 7)
Dihedral(4) = Array(4, 0, 1, 2, 3, 9, 5, 6, 7, 8)
Dihedral(5) = Array(5, 9, 8, 7, 6, 0, 4, 3, 2, 1)
Dihedral(6) = Array(6, 5, 9, 8, 7, 1, 0, 4, 3, 2)
Dihedral(7) = Array(7, 6, 5, 9, 8, 2, 1, 0, 4, 3)
Dihedral(8) = Array(8, 7, 6, 5, 9, 3, 2, 1, 0, 4)
Dihedral(9) = Array(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
'create the FunctionF array
FnF(0) = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
FnF(1) = Array(1, 5, 7, 6, 2, 8, 3, 0, 9, 4)
'compute the rest of the FunctionF array
For i = 2 To 7
FnF (i) = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
For j = 0 To 9
FnF (i)(j) = FnF(i - 1)(FnF(1)(j))
Next
Next
'Create the InverseD5 array
InverseD5 = Array("0", "4", "3", "2", "1", "5", "6", "7", "8", "9")
End Sub

...