From: Panu.Juvonen@hut.fi (Panu Juvonen)
Subject: Re: Viitekoodin ja tilinumeron tarkkari
Reply-To: Panu.Juvonen@hut.fi
Organization: Helsinki University of Technology, Finland
Distribution: sfnet
Date: 23 Aug 92 18:10:59



Tilinumeroiden tarkiste lasketaan aina tilinumeron konekielisest{ muodosta.
Konekielinen muoto tilinumerolle saadaan seuraavasti:

Rahalaitos m{{r{ytyy tilinumeron alun perusteella seuraavasti:

KOP = 1, SYP = 2, SKOP ja s{{st|pankit = 4, OKO ja osuuspankit = 5,
]AB = 6, STS = 71, PPOY = 70 ja PSP = 8.

(N{m{ olivat vuonna 1989, sen j{lkeen on voinut tulla muutoksia, en tied{).

KOP:n, SYP:n, PPOY:n ja PSP:n tilinumeroihin lis{t{{n v{linollat vasemmalta
lukien kuudennen numeron j{lkeen siten, ett{ 14 numeroa t{yttyy.
SKOP:n, s{{st|pankkien ja STS:n sek{ OKO:n ja osuuspankkien tilinumeroihin
lis{t{{n v{linollat vasemmalta lukien seitsem{nnen numeron j{lkeen siten,
ett{ 14 numeroa t{yttyy. (PSP:n muut kuin s{{st|tilit alkavat kuudella 8:lla,
ja s{{st|tilit yhdell{ 8:lla.)
]AB:n tilinumerot ovat aina konekielisess{ muodossa.

Itse tarkiste lasketaan seuraavasti:


Kaava 1 (muut kuin PSP) :

Tarkiste lasketaan tilinumeron 13 ensimm{isest{ merkist{ 10-modulilla
painoin 2121212121212. Tarkiste merkit{{n tilinumeron 14. merkiksi.

Tilinumeron numerot kerrotaan painoilla. Saatujen tulojen numerot lasketaan
yhteen ja saatu summa v{hennet{{n seuraavasta kymmenell{ jaollisesta luvusta.

Esim.	Tilinro eilman tarkistetta	5000156000012
	Painot				2121212121212
	Tulot				!   !!!    !!- 4	4
					!   !!!    !-- 1	1
					!   !!!-------12      1+2
					!   !!-------- 5	5
					!   !--------- 2	2
					!-------------10      1+0
							      ---
					Summa                  16

					Tarkiste 20-16 = 4


Kaava 2 (PSP:n k{ytt|-, siirto-, ja karttuvat talletustilit) :

Tarkiste lasketaan seitsem{nmerkkiselle tilinumerolle siten, ett{ kukin
numero kerrotaan painoarvollaan, jotka ovat vasemmalta lukien 7137137.
Kertolaskun tulot lasketaan yhteen ja summa v{hennet{{n seuraavasta
kymmenell{ jaollisesta luvusta. Saatu erotus on tarkiste.

Esim.	Tilinumero ilman tarkistetta	8888880484700
	Painot				      7137137
					       !!!!-- 7
					       !!!---28
					       !!----24
					       !----- 4
						     --
					Summa	     63
	
					Tarkiste 70 - 63 = 7

PSP:n s{{st|tileille ei lasketa tarkistetta.

L{hde: KOP:n ohje tilinumeron rakenteesta 11.10.1989.


Per{ss{ onpi k{ytt{m{ni rutiinit pankkitilin konemuodon laskentaan,
tilinumeron tarkistukseen, henkil|numeron tarkistukseen ja viitenumeron
laskemiseen (tehty Turbo Pascalilla, ja niit{ voisi taatusti parantaa
jos haluaisi, mutta mit{ turhia, ne kun toimii :) . Rutiinit eiv{t v{ltt{-
m{tt{ ole muutenkaan hirve{n selvi{, ne kun on tehty omaan k{ytt||n,
ja kommentointikin on mahtava, mutta asia niist{ pit{isi kuitenkin selvit{.).


unit BankUnit;

interface

uses
  Crt,
  General;

type
  ViitetietoTyyppi = string [20];
  PankkitiliTyyppi = string [14];
  SosTunnusTyyppi  = string [11];

function Konemuoto(Pankki,Tili : PankkitiliTyyppi) : PankkitiliTyyppi;

function TarkistaTili(Pankki,Tili : PankkitiliTyyppi) : boolean;

function TarkistaSosTunnus(SosTunnus : SosTunnusTyyppi) : boolean;

function Viitetieto(Numero : ViitetietoTyyppi) : ViitetietoTyyppi;

implementation

const
  KOP  = 1;
  SYP  = 2;
  SKOP = 4;
  OKO  = 5;
  AAB  = 6;
  STS  = 71;
  PPOY = 70;
  PSP  = 8;

function Konemuoto(Pankki,Tili : PankkitiliTyyppi) : PankkitiliTyyppi;
var
  Bank : byte;
  A    : integer;
begin
  Pankki := UpcaseStr(Pankki);

{ Mahdolliset valilyonnit makeen }

  A := 1;
  while A <= length(Tili) do
    if Tili[A] = ' '
      then delete(Tili,A,1)
      else inc(A);
  if (copy(Pankki,1,3) = 'PSP') or (copy(Pankki,1,11) = 'POSTIPANKKI')
   then begin
    if length(Tili) < 9 then begin
      if  (pos('-',Tili) > 0) then delete(Tili,pos('-',Tili),1);
      Tili := '888888-'+Tili;
    end else
      if Tili[1] <> '8' then Tili := '8'+Tili;
  end;
  if Tili[7] <> '-' then begin
    Konemuoto := '';
    exit;
  end;
  delete(Tili,7,1);
  val(Tili[1],Bank,A);
  if Bank = 7 then val(copy(Tili,1,2),Bank,A);
  if A <> 0 then begin
    Konemuoto := '';
    exit;
  end;
  if Bank in [KOP,SYP,PSP,PPOY] then
    while length(Tili) < 14 do insert('0',Tili,7);
  if Bank in [SKOP,OKO,STS] then
    while length(Tili) < 14 do insert('0',Tili,8);
  Konemuoto := Tili;
end;     { of Konemuoto }

function TarkistaTili(Pankki,Tili : PankkitiliTyyppi) : boolean;
const
  Weight : array [1..2,1..13] of integer =
    ((2,1,2,1,2,1,2,1,2,1,2,1,2),
     (0,0,0,0,0,0,7,1,3,7,1,3,7));
var
  A,B   : integer;
  Sum   : integer;
  Value : integer;
  Next  : integer;
  Tulos : integer;
  Bank  : byte;
begin
  Tili := Konemuoto(Pankki,Tili);
  if Tili = '' then begin
    TarkistaTili := false;
    exit;
  end;
  for A := 1 to 14 do begin
    val(Tili[A],Value,B);
    if B <> 0 then begin      { ei numero }
      TarkistaTili := false;
      exit;
    end;
  end;
  if Tili[1] <> '8'   { muut kuin PSP }
    then Bank := 1
    else Bank := 2;
  if (Bank = 2) and (copy(Tili,1,6) <> '888888') then begin 
{ PSP:n s{{st|tili }
    TarkistaTili := true;
    exit;
  end;
  Sum := 0;
  for A := 1 to 13 do begin
    val(Tili[A],Value,B);
    Tulos := Value*Weight[Bank,A];
    if Bank = 1
      then Sum := Sum+(Tulos div 10)+(Tulos mod 10)
      else Sum := Sum+Tulos;
  end;
  Next := Sum;
  while Next mod 10 <> 0 do inc(Next);
  if FStr(Next-Sum,1,0) <> Tili[14]
    then TarkistaTili := false
    else TarkistaTili := true;
end;     { of TarkistaTili }

function TarkistaSosTunnus(SosTunnus : SosTunnusTyyppi) : boolean;
const
  Tarkisteet : string [31] = '0123456789ABCDEFHJKLMNPRSTUVWXY';
var
  SosNumero : longint;
  A         : integer;
begin
  if (pos('-',SosTunnus) <> 7) or (length(SosTunnus) <> 11) then begin
    TarkistaSosTunnus := false;
    exit;
  end;
  delete(SosTunnus,7,1);
  val(copy(SosTunnus,1,9),SosNumero,A);
  if A <> 0 then begin
    TarkistaSosTunnus := false;
    exit;
  end;
  if Tarkisteet[(SosNumero mod 31)+1] <> SosTunnus[11]
    then TarkistaSosTunnus := false
    else TarkistaSosTunnus := true;
end;     { of TarkistaSosTunnus }

function Viitetieto(Numero : ViitetietoTyyppi) : ViitetietoTyyppi;
const
  Weight : array [1..19] of integer =
     (7,1,3,7,1,3,7,1,3,7,1,3,7,1,3,7,1,3,7);
var
  A,B : integer;
  Sum : integer;
  Value : integer;
  Next  : integer;
begin
  Viitetieto := '';
  while length(Numero) < 19 do
    Numero := '0'+Numero;
  Sum := 0;
  for A := 1 to 19 do begin
    val(Numero[A],Value,B);
    if B <> 0 then exit;
    Sum := Sum+Value*Weight[A];
  end;
  Next := Sum;
  while Next mod 10 <> 0 do inc(Next);
  Viitetieto := Numero+FStr(Next-Sum,1,0);
end;     { of Viitetieto }

end.


(P.S. yo. unit k{ytt{{ n{{mm{ muutamaa rutiinia General-unitistani, jossa
on kaikenlaista sekalaista rutiinia, mutta niiden merkitys pit{isi olla
varsin selv{ koodista. Jos ei ole niin mailata voi.).

--
Panu Juvonen

"i'm tired in general and sleepy in particular.
 i have a great desire to move elsewhere."
	- excerpt from 'work' by Andrei Codrescu

Email address : Panu.Juvonen@hut.fi (preferred)
           or : juvonen@vipunen.hut.fi

Newsgroups: sfnet.atk.ms-dos