Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 20:55 Der er 17 kommentarer og
1 løsning

At beregne CVC for et kreditkort

Er der nogen derude der har algoritmen til at beregne denne? Helst i C#, men sålænge jeg kan pille algoritmen ud, er sproget umiddelbart ikke så vigtigt :-)

/JJ
Avatar billede nielle Nybegynder
12. maj 2005 - 21:08 #1
CVC nummeret kan ikke beregnes. Sikkerheden ligger netop i at man skal have kortet fysisk i hånden for at kunne aflæse det.
Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 21:26 #2
DIBS gør det i stor stil med et kæmpe javascript, så jeg ved at det kan lade sig gøre...
Avatar billede nielle Nybegynder
12. maj 2005 - 21:30 #3
Og du er 100% sikker på at deres script ikke kalder PBS og validere det hos dem?
Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 21:34 #4
Helt sikker - her ligger en del af Javascriptet:

https://payment.architrade.com/payment/powerforms/regexp.xml.js

Og resten kan jeg pt ikke få adgang til, da det kræver at man sådn ca gennemfører en transaktion hos dem..det kan gøres ved at lægge en ordre hos f.eks. SHG, og så komme til siden hvor kortnummer, cvc & datoer skal indtastes - siden hedder https://payment.architrade.com/payment/paytype.pml, men kan kun tilgåes når man kommer fra en shop som benytter sig af denne.
Avatar billede nielle Nybegynder
12. maj 2005 - 21:41 #5
Det fremgår nu ikke af den js-stump at de kan beregne CVC nummeret - aller højst at de kan validere det. Formentligt va en modulus-13 tjek eller noget i den stil.
Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 21:44 #6
argh, undskyld...jeg har misledt dig (/resten af befolkningen på eksperten.dk) - jeg skal naturligvis kun ha valideret en CVC :-)

Jeg har koden liggende lokalt, omend jeg lige skal ha strippet den for visse private oplysninger.

Jeg har ikke været i stand til at hive noget brugbar kode ud af det JS jeg har linket til, men du nævner et modulus-13 tjek?
Avatar billede nielle Nybegynder
12. maj 2005 - 21:54 #7
Jeg har ledt og ledt, men jeg har ikke kunnet finde mere om det andre steder. Desværre. :^(

Modulus-13 validering er dog en almindelig teknik som bruges i mange sammenhænge hvor man har et tal og gerne vil kunen sikre at brugeren ikke er kommet til at skrive galt. F.eks. i CPR-numre, i CVS-numre, i ISBN-numre og altså også i CreditCard-numre. Problemet er at det ikke er den samme algoritme man bruger overalt, og jeg har ingen anelse om hvordan den ser ud for CC-numre med og uden CVC. Som sagt, desværre. :^(
Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 21:56 #8
Ville det kunne hjælpe hvis jeg postede kildekoden til siden med funktionerne?
Avatar billede nielle Nybegynder
12. maj 2005 - 22:08 #9
Måske. Uden at vide hvad der står kan jeg jo ikke garantere noget. :^|
Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 22:14 #10
<script type="text/javascript"><!--
var helpwin = null;
function showhelp(a) {
  help = window.open('help.pml#' + a,
                    'help',
                    'width=500,height=400,resizable=yes,scrollbars=yes',true);
  help.focus();
}

function removespaces(s) {
  return s.split(' ').join('');
}

function checkmodulo11(s) {
  if (s.length != 11) {
    return true;
  }
  var sum;
  var c = new Array(11);
  for (var i = 0 ; i < 11 ; i++) {
    c[i] = s.charAt(i) - '0';
  }
  sum = 5 * c[0] + 4 * c[1] + 3 * c[2] + 2 * c[3] + 7 * c[4] + 6 * c[5] + 5 * c[6] + 4 * c[7] + 3 * c[8] + 2 * c[9] + c[10];
  return sum % 11 == 0;
}

function checkmodulo10(s) {
  if (s.length != 16) {
    return true;
  }
  var sum = 0;
  for (var i = 0 ; i < 16 ; i++) {
    numval = s.charAt(i) - '0';
    if (i % 2 == 0) {
      numval *= 2;
      if (numval >= 10) {
        sum += 1 + numval % 10;
      }
      else {
        sum += numval;
      }
    }
    else {
      sum += numval;
    }
  }
  return sum %10 == 0;
}

function checkmodulo(s) {
  var s1 = removespaces(s);
  return checkmodulo10(s1) && checkmodulo11(s1);
}

var clicked = false;
function doSubmit(button) {
  if (!clicked && submitHandler(0)) {
    clicked = true;
    button.form.submit();
  }
}

function setFocus() {
  document.payform.cardno.focus();
}
//--></script>
<script type="text/javascript"><!--
var newwin = listwin = null;

function handlePopup() {
  document.payform.submit();
  return true;
}

function closePopup(noconf) {
  if (newwin && !newwin.closed) {
    if (noconf || confirm('')) {
      document.payform.action = 'close.pml';
      document.payform.submit();
      return true;
    }
    return false;
  }
  return true;
}

function showlistwin() {
  listwin = window.open('http://payment.architrade.com/butiks_hvem.pml',
                        'Forretninger',
                        'width=480,height=600,status=no,menubar=0,scrollbars=yes,resizable=yes');
  listwin.focus();
}

window.onresize = function() {
  var tables = document.getElementsByTagName('table');
  for (var i = 0; i < tables.length; i++) {
    if (tables[i].className == 'fullsize') {
      tables[i].style.height = getClientHeight() - 231 + 'px';
    }
  }
}

window.onload = function() {
  disableAutoComplete();
  onresize();
  document.getElementsByTagName('body')[0].style.overflow = 'auto';
  if (window.name == 'Betaling' && getClientWidth() < 500) {
    window.resizeTo(550, 600);
    location.reload();
  }
  setFocus();
}

window.onunload = function() {
  closePopup(true);
}

//--></script>
</head>
<body>

<script type="text/javascript" src="powerforms/regexp.xml.js"></script>
<script type="text/javascript">
var powerforms_red = new Image();
var powerforms_yellow = new Image();
var powerforms_green = new Image();
var powerforms_na = new Image();
var powerforms_info = new Array(new Array(), new Array(), new Array());
var powerforms_applets = new Array(new Array(), new Array(), new Array());

var regexp_anychar = new Array(new Array(false, '\x00', '\xFF', 1), new Array(true));
var regexp_anything = new Array(new Array(true, '\x00', '\xFF', 0));
var regexp_1 = new Array(
  new Array(false, '0', '9', 1),
  new Array(false, ' ', ' ', 2, '0', '9', 3),
  new Array(false, '0', '9', 3),
  new Array(false, ' ', ' ', 4, '0', '9', 5),
  new Array(false, '0', '9', 5),
  new Array(false, ' ', ' ', 6, '0', '9', 7),
  new Array(false, '0', '9', 7),
  new Array(false, ' ', ' ', 8, '0', '9', 9),
  new Array(false, '0', '9', 9),
  new Array(false, ' ', ' ', 10, '0', '9', 11),
  new Array(false, '0', '9', 11),
  new Array(false, ' ', ' ', 12, '0', '9', 13),
  new Array(false, '0', '9', 13),
  new Array(false, ' ', ' ', 14, '0', '9', 15),
  new Array(false, '0', '9', 15),
  new Array(false, ' ', ' ', 16, '0', '9', 17),
  new Array(false, '0', '9', 17),
  new Array(false, ' ', ' ', 18, '0', '9', 19),
  new Array(false, '0', '9', 19),
  new Array(false, ' ', ' ', 20, '0', '9', 21),
  new Array(false, '0', '9', 21),
  new Array(false, ' ', ' ', 22, '0', '9', 23),
  new Array(false, '0', '9', 23),
  new Array(true, ' ', ' ', 24),
  new Array(true));

var powerforms_error_title = "Fejl i indtastning.";
powerforms_red.src = "powerforms/cr_red.gif";
powerforms_yellow.src = "powerforms/yellow.gif";
powerforms_green.src = "powerforms/cr_green.gif";
powerforms_na.src = "powerforms/na.gif";
</script>
<script type="text/javascript" src="powerforms/PowerForms.js"></script>
<form onsubmit="return submitHandler(0);" method="post" name="payform" action="/payment/card.pfml"><script type="text/javascript">
function update_form0_1(show_info) {
  var format;
  var help = null;
  var error = "Det indtastede kortnummer er ikke et korrekt kortnummer. ";

if (document.forms[0].modulook.value == "0") {
format = regexp_1;
} else {
format = regexp_card_2;
}

  var change = (powerforms_info[0][1][2] != format);
  powerforms_info[0][1][2] = format;
  powerforms_info[0][1][3] = help;
  powerforms_info[0][1][4] = error;
  updateField(0, 1, show_info);
  return change;
}

function update_form0_4(show_info) {
  var format;
  var help = null;
  var error = "Indtast kontrolcifre (3 cifre).";

format = regexp_cvc;

  var change = (powerforms_info[0][4][2] != format);
  powerforms_info[0][4][2] = format;
  powerforms_info[0][4][3] = help;
  powerforms_info[0][4][4] = error;
  updateField(0, 4, show_info);
  return change;
}

function update_form0_3(show_info) {
  var format;
  var help = null;
  var error = "Indtast årstal.";

format = regexp_year;

  var change = (powerforms_info[0][3][2] != format);
  powerforms_info[0][3][2] = format;
  powerforms_info[0][3][3] = help;
  powerforms_info[0][3][4] = error;
  updateField(0, 3, show_info);
  return change;
}

function update_form0_2(show_info) {
  var format;
  var help = null;
  var error = "Indtast måned mellem 01 og 12.";

format = regexp_month;

  var change = (powerforms_info[0][2][2] != format);
  powerforms_info[0][2][2] = format;
  powerforms_info[0][2][3] = help;
  powerforms_info[0][2][4] = error;
  updateField(0, 2, show_info);
  return change;
}

</script>

<input name="modulook" value="0" type="hidden" />

<input maxlength="38" name="cardno" onchange="this.form.modulook.value=(checkmodulo(this.value) ? 1 : 0);; update_form0(null);" onkeyup="this.form.modulook.value=(checkmodulo(this.value) ? 1 : 0);; update_form0_1(true);" value="" size="22" tabindex="1" type="text" /><img src="powerforms/na.gif" align="middle" width="15" height="15" alt="" /><script type="text/javascript">powerforms_info[0][1] = new Array(document.forms[0].elements[document.forms[0].elements.length - 1], document.images[document.images.length - 1], null, null, null);</script></div>
<input onkeyup="update_form0_2(true);" onchange="update_form0(null);" maxlength="2" name="expmon" value="" size="4" tabindex="2" type="text" /><img src="powerforms/na.gif" align="middle" width="15" height="15" alt="" /><script type="text/javascript">powerforms_info[0][2] = new Array(document.forms[0].elements[document.forms[0].elements.length - 1], document.images[document.images.length - 1], null, null, null);</script></div>
<input onkeyup="update_form0_3(true);" onchange="update_form0(null);" maxlength="2" name="expyear" value="" size="4" tabindex="3" type="text" /><img src="powerforms/na.gif" align="middle" width="15" height="15" alt="" /><script type="text/javascript">powerforms_info[0][3] = new Array(document.forms[0].elements[document.forms[0].elements.length - 1], document.images[document.images.length - 1], null, null, null);</script></div>
<input onkeyup="update_form0_4(true);" onchange="update_form0(null);" name="cvc" maxlength="3" value="" size="7" tabindex="4" type="text" /><img src="powerforms/na.gif" align="middle" width="15" height="15" alt="" /><script type="text/javascript">powerforms_info[0][4] = new Array(document.forms[0].elements[document.forms[0].elements.length - 1], document.images[document.images.length - 1], null, null, null);</script></div>
<input name="pay" onclick="doSubmit(this)" value="Udf&oslash;r betaling" tabindex="5" type="button" />

<script type="text/javascript">
function update_form0(caller) {
  var change;

  do {
    change = false;
    change = update_form0_1(false) || change;
    change = update_form0_2(false) || change;
    change = update_form0_3(false) || change;
    change = update_form0_4(false) || change;
  } while (change);

  if (caller != null) {
    caller.focus();
  }
}
update_form0(null);
</script>
</form>
         

<script type="text/javascript"><!--
function goBack(f) {
  doBack = true;

  doBack = false;
  f.submit();

  doBack = false;
  setTimeout('self.close();', 1000);
  opener.focus();
if (doBack) { history.back(0); }
}
//--></script>

<form onsubmit="return submitHandler(1);" method="post" name="cancelform" action="http://www.shg.dk/shop/bestil.asp" target="main" style="padding:0px;margin-bottom:0px;"><script type="text/javascript">
</script>

<input name="cancel" onclick="if (closePopup(true)) goBack(this.form)" value="Afbryd" type="button" />
<script type="text/javascript">
function update_form1(caller) {
  var change;

  do {
    change = false;
  } while (change);

  if (caller != null) {
    caller.focus();
  }
}
update_form1(null);
</script>
</form>

<form onsubmit="return submitHandler(2);" action="orderdetail.pml" method="post" name="orderdetail"><script type="text/javascript">
</script>
<input name="return" value="/payment/card.pfml" type="hidden" />
       
<script type="text/javascript">
function update_form2(caller) {
  var change;

  do {
    change = false;
  } while (change);

  if (caller != null) {
    caller.focus();
  }
}
update_form2(null);
</script>
</form>
<a href="orderdetail.pml" onclick="if (closePopup()) document.orderdetail.submit(); return false;">Flere oplysninger</a>
Avatar billede nielle Nybegynder
12. maj 2005 - 22:24 #11
Ok, det var så ikke et Modulus-13, men derimod et Modulus-10 tjek (funktionen checkmodulo10(...)). Der kan man bare se.

Jeg kigger på det, men der kommer jo nok til at gå lidt tid med den bunke kode. :^)
Avatar billede j_jorgensen Nybegynder
12. maj 2005 - 22:26 #12
Men er det ikke kun til check af kortnummeret, det check? så vidt jeg kan se er de interessante dele følgende:

var regexp_cvc = new Array(
  new Array(false, '0', '9', 1),
  new Array(false, '0', '9', 2),
  new Array(false, '0', '9', 3),
  new Array(true));

fra regexp.xml.js



og

function update_form0_4(show_info) {
  var format;
  var help = null;
  var error = "Indtast kontrolcifre (3 cifre).";

format = regexp_cvc;

  var change = (powerforms_info[0][4][2] != format);
  powerforms_info[0][4][2] = format;
  powerforms_info[0][4][3] = help;
  powerforms_info[0][4][4] = error;
  updateField(0, 4, show_info);
  return change;
}

samt kaldet heraf:

<input onkeyup="update_form0_4(true);" onchange="update_form0(null);" name="cvc" maxlength="3" value="" size="7" tabindex="4" type="text" />
Avatar billede nielle Nybegynder
12. maj 2005 - 22:59 #13
Du har helt ret, Mod-10 tjekket er på CC-numeret uden CVC-nummer (kun 16 cifre). Din analyse ser også ud til at være i orden (svarere i hvert fald til hvad jeg selv er kommet frem til), og da der ikke er noget tjek i den der kode er jeg tilbøjelig til at mene at den eneste validering der er er på om der er 3 cifre eller ej - men koden til dette kan jeg faktisk heller ikke se noget sted.

Der er stadig et par ting jeg skal have undersøgt før jeg kan sige det endeligt, men nu er klokken mange nok til at jeg bliver nødt til at smutte - lover at kigge på det i morgen. G'nat.
Avatar billede nielle Nybegynder
14. maj 2005 - 09:01 #14
Hej igen,

Jeg mangler koden for funktionen updateField(...) for at kunne sige noget definitivt. Denne kaldes som en det af valideringen af CVC feltet:

function update_form0_4(show_info)
{
    var format;
    var help = null;
    var error = "Indtast kontrolcifre (3 cifre).";

    format = regexp_cvc;

    var change = (powerforms_info[0][4][2] != format);
    powerforms_info[0][4][2] = format;
    powerforms_info[0][4][3] = help;
    powerforms_info[0][4][4] = error;
    updateField(0, 4, show_info);
    return change;
}

Men der er en del ting som allerede nu får mig til at tro at "valideringen" af CVC nummeret blot består i en test af om der står 3 cifre i feltet, og ikke andet.

1) Formatet hedder ”regexp_cvc” hvilket vel må tyde ret kraftigt på at der er tale om en validering som benytter Regular Expressions.

2) regexp_cvc har værdien:

var regexp_cvc = new Array(
    new Array(false, '0', '9', 1),
    new Array(false, '0', '9', 2),
    new Array(false, '0', '9', 3),
    new Array(true));

Det regulære udtryk for test af om der et tale om netop 3 cifre lyder sådan:

[0-9][0-9][0-9]

Der synes at være en vis sammenlignelighed mellem dette og de tre første poster.

3) Dette understøttes af nogle af de andre arrays som vi også finder i filen regexp.xml.js, f.eks. disse to:

var regexp_upper = new Array(
    new Array(false, 'A', 'Z', 1),
    new Array(true));

var regexp_lower = new Array(
    new Array(false, 'a', 'z', 1),
    new Array(true));

- som vel næsten må være til at validere store bogstaver (RegExp = [A-Z]) hhv. små bogstaver (RegExp = [a-z]).

4) Man kan selvfølgelig påpege at det selvfølgelig er en del af valideringen af et CVC nummer at man først tjekker at det består af netop 3 cifre. Men, hvis dette er tilfældet så må selve valideringen altså befinde sig i funktionen updateField(...).

Imidlertid er der nogle stærke argumenter imod dette:

5) Det ser ikke ud til at updateField(...) returnere nogen værdi. Måske gør den det via referenceoverførelse til arrayet show_info, men det ser heller ikke ud til at noget derfor bliver brugt senere.

6) updateField(...) kaldes flere steder i koden, og kun et af disse steder er det for et CVC nummer. Hvordan skelner den så på dette tilfælde og alle de andre tilfælde?

Summa-sumarum:

Jeg kan intet endeligt sige før at jeg har set koden for updateField(...), men det ser ikke ud til at denne modtager andet information end at et sådant skal bestå af 3 cifre. Så jeg tror ikke ret meget på at det er nogen egentlig validering.
Avatar billede j_jorgensen Nybegynder
14. maj 2005 - 10:36 #15
Jeg har nu brugt...en god sjat timer på at researche CVC/CCC/CID koder..og det ser ud til at de ikke kan beregnes uden ejerens kontonummer blandt andet - det plus visse andre faktorer bliver krypteret med 3DES, og en del af outputtet er således CVC koden, så jeg tror ikke at det kan lade sig gøre.

På ældre kort, var CVC koden bestemte cifre af kortnummeret, men det ser ikke ud til at holde længere :/

Tak for din research & tid - tror ikke at det er nødvendigt at checke updateField() :-)  Læg bare et svar.
Avatar billede nielle Nybegynder
14. maj 2005 - 11:13 #16
Jeg mener altså også at CVC nummeret kun er noget som banken kan slå op i deres database. Men da du lagde ud med at fortælle at DIPS validerede det blev jeg nu alligevel i tvivl. Efter at have gennemtrævlet JS koden så tror jeg - som sagt - at deres validering udelukkende består i at der er 3 cifre. Ikke noget avanceret med modulus-13, -11 eller 10 tjek. Desværre.
Avatar billede nielle Nybegynder
14. maj 2005 - 11:13 #17
Og et svar :^)
Avatar billede nielle Nybegynder
19. maj 2005 - 19:11 #18
?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester