1 (edited by zygis 2010-04-27 15:02:16)

Topic: banklinkai, utf-8 ir windows-1257

Situacija tokia: gaunu iš banko atsakymą windows-1257 formatu. Bandant tikrinti VK_MAC gaunu atsakymą, kad neteisingas VK_MAC. Viskas veikia aišku kol nėra lietuviškų rašmenų duomenų eilutėje, kurią pasirašė bankas. Išbandžiau krūvą variantų, keisdamas lietuviškas raides į "sugadintas" ir neveikia nors tu ką...
Variantai: Ðuklevièienë, Å uklevičienÄ—,šuklevičienė. VK_MAC būna užkoduotas su base64 tai duomenys kaip ir "nepažeidžiami", blyn nebežinau ką ir daryti...
Gal kas žinote/numanote sprendimą?

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: banklinkai, utf-8 ir windows-1257

O tai kaip vyksta tas "tikrinimas", kuris pasako, kad rezultatas blogas? Kokios jis koduotės tikisi, utf8?

Re: banklinkai, utf-8 ir windows-1257

header('Content-Type: text/html; charset=utf-8');
echo iconv('Windows-1257','UTF-8',utf8_decode('Ðuklevièienë'));
Kiek maigyklių sudėvėjai ?

4 (edited by Ramex 2010-04-28 13:19:44)

Re: banklinkai, utf-8 ir windows-1257

Kažkada man teko su šita nesamone dirbt, tai veikiantį sprendimą pasiekiau taip:
Failas, iš kurio siunčiama informacija į banką

<?php

$HP = array
    (
        'VK_SERVICE'     => '1001', 
        'VK_VERSION'     => '008', 
        'VK_SND_ID'     => '', 
        'VK_STAMP'         => '', 
        'VK_AMOUNT'     => '0.01', 
        'VK_CURR'         => 'LTL', 
        'VK_ACC'         => '', 
        'VK_PANK'         => '73000',
        'VK_NAME'         => '',
        'VK_REF'         => '', 
        'VK_MSG'         => 'Mokėjimas už prekę',
        'VK_MAC'         => '',
        'VK_RETURN'     => '',
        'VK_LANG'         => 'LIT'
    );

$VKMac = array(
    $HP['VK_SERVICE'], 
    $HP['VK_VERSION'], 
    $HP['VK_SND_ID'], 
    $HP['VK_STAMP'], 
    $HP['VK_AMOUNT'], 
    $HP['VK_CURR'], 
    $HP['VK_ACC'], 
    $HP['VK_PANK'], 
    $HP['VK_NAME'], 
    $HP['VK_REF'], 
    $HP['VK_MSG'] );
    
$mac = '';

    foreach($VKMac as $str) {
        $sl = strlen($str);
        if($sl > 0 && $sl < 10) {
            $mac .= "00".$sl.$str;
        }
        if($sl > 9 && $sl < 100) {
            $mac .= "0".$sl.$str;
        }
        if($sl > 99 && $sl < 1000) {
            $mac .= $sl.$str;
        }
    }

$fp = fopen("private.pem", "r");
$priv_key = fread($fp, 8192);
fclose($fp);
$pkeyid = openssl_get_privatekey($priv_key);

openssl_sign($mac, $signature, $pkeyid);
$signature = base64_encode($signature);
$signature = preg_replace("/[\r|\n]/", "", $signature);
openssl_free_key($pkeyid);
    
$HP['VK_MAC'] = $signature;

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html>

<head>

<title>BankLink</title>


<base href="" />
<meta name="Generator" content="" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1257" />
<meta name="keywords" content="" />
<meta name="description" content="" />

</head>

<body>

<div><?php echo $mac; ?></div>

<div class="container">
    <form name="bankLinkForm" action="https://ib.swedbank.lt/banklink/" method="post">
    
<?php

    foreach($HP as $key => $value) {
        echo '<input style="width: 300px;" type="text" name="'.$key.'" value="'.$value.'" /><br />'."\n";
    }

?>
        
        <button type="submit">siųsti</button>
    </form>
</div>

</body>
</html>

Failas, kuris priima informaciją

<?php
header('Content-Type: text/html; charset=ISO-8859-13');

$HP = $_POST;

$VKMac = array(
    $HP['VK_SERVICE'], 
    $HP['VK_VERSION'], 
    $HP['VK_SND_ID'], 
    $HP['VK_REC_ID'], 
    $HP['VK_STAMP'], 
    $HP['VK_AMOUNT'], 
    $HP['VK_CURR'], 
    $HP['VK_REC_ACC'], 
    $HP['VK_REC_NAME'], 
    $HP['VK_SND_ACC'], 
    $HP['VK_SND_NAME'], 
    $HP['VK_REF'], 
    $HP['VK_MSG'], 
    $HP['VK_T_DATE'] );

$fp = fopen("cert.pem", "r");
$pub_key = fread($fp, 8192);
fclose($fp);
$pkeyid = openssl_get_publickey($pub_key);

$mac = '';

    foreach($VKMac as $str) {
        //$str = iconv('ISO-8859-13', 'Windows-1257', $str);
        $sl = strlen($str);
        if($sl > 0 && $sl < 10) {
            $mac .= "00".$sl.$str;
        }
        if($sl > 9 && $sl < 100) {
            $mac .= "0".$sl.$str;
        }
        if($sl > 99 && $sl < 1000) {
            $mac .= $sl.$str;
        }
    }
    
$ok = openssl_verify($mac, base64_decode($HP['VK_MAC']), $pkeyid); 
if ($ok == 1) {
   echo "Good signature"; 
} elseif ($ok == 0) {
   echo "Bad signature"; 
} else {
   echo "Error checking signature"; 
}
openssl_free_key($pkeyid);

?>

Tik va nepamenu ar eilutė

$str = iconv('ISO-8859-13', 'Windows-1257', $str);

būtina ar ne. čia aišku galima pasibandyti ir bus matyti.
Beje, failų koduotė buvo ANSI.

Su sąlyga, kad šūdo nebus...

Re: banklinkai, utf-8 ir windows-1257

Na pagaliau radau laiko vėl prisėsti. Tai va neveikia :)
Bandau mąstyti logiškai:
Bankas naudoja windows-1257 ir turi tokią eilutę:

00411010030080091120292700093024725930101272284889010BVIL000010006999.99003LTL020LT834010042400929308026UAB "Geros kainos prekyba"020LT474010049500473058021šuklevičienė Kristina009300000020018Prekiu apmokejimas0102010.04.26

tuomet bankas pasirašo šią eilutę su openssl_sign ir užkodina eilutę su base64_encode. Ir viską siunčia man. Pas mane sistema užklausą priėmė, ir įkalė į tekstinį failą, vėlesniai peržiūrai. Ikalė aišku utf-8 formatu :). Tai va, dabar paemu ta pačią eilute tik vieną užkoduotą su sertifikatu , o kitą ne. Tikrinimas vyksta su openssl_verify . Ir man reikia "sutvarkyti" neužkoduotą eilutę taip, kad būtų lygiai tokia pati, kaip ir ta kurią bankas pasirašė su savo sertifikatu...
Nesinori kas kart rašinėti bankui, kad davai bandykit užklausą siūsti iš naujo...
Ir vat kaip liūdna dabar :(

to Ramex: pas tave ir taip sistema laikosi ant windows-1257, tai su encodingais nieko keisti ir nereikia...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: banklinkai, utf-8 ir windows-1257

zygis: yra toks dalykas - duomenų laikymas tam tikroje koduotėje ir paskui jų interpretavimas.

Man iš ko ką parašei yra iki galo neaišku: ar tu išsaugodamas į failą duomenis dar juos ir atitinkamai pakonvertuoji "windows-1257" -> "utf-8" ar tik į utf-8 koduotės failą rašai. Jeigu neatlieki jokios konversijos, tai tau atvertinėti ir nereikia tų duomenų, tik teisingai interpetuoti, kaip "windows-1257". Bent jau aš taip suprantu.

Re: banklinkai, utf-8 ir windows-1257

na buvo paprasčiausia fwrite(failas, print_r($_POST, TRUE)); dabar tikrinimui ranka kode susirašau reikšmes į masyvą ir bandau tikrinti duomenis. Failas buvo tiesiog testavimui, ir iš anksto nepagalvota apie encodingų skirtumą... Ir dabar gaunasi taip, kad bandau atspėti kokią eilutę pasirašė bankas :)

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: banklinkai, utf-8 ir windows-1257

na visų pirma aš nesuprantu, kodėl tau reikia prašinėt banko, kad tau kažką siuntinėtų..? juk sutartis pasirašyta, parašais esate apsikeitę, tai viskas turėtų veikti automatiškai.
o visų antra, tai kas tau trukdo tesingai konvertuoti duomenis prieš tai, kai su jais kažką darai. arba naudoti duomenų apdorojimui scriptus kaip pateikiau aš, su nurodytom koduotėm, o po to perkoduoti taip kaip reikia tau ir naudoti jau kitose vietose?

Su sąlyga, kad šūdo nebus...

Re: banklinkai, utf-8 ir windows-1257

na prašymas buvo bankui pratestuoti pirkimą, nes sistema nėra pagaminta, o tikrų sąskaitų dar niekas neduoda. pratestuoti gali tik banko darbuotojai... Testavimo faktas jau įvyko, užklausa teisinga ir buvo grąžintas atsakymas. Su "sugadintu" atsakymu reikia susikonstruoti sistemą kuri veiks. Kitų koduočių kaip utf-8 naudoti negaliu, nes mokejimų moduliukas tik didelės sistemos sraigtelis...

MongoDB Certified Developer
MongoDB Certified DBA
Zend Certified Engineer

Re: banklinkai, utf-8 ir windows-1257

na aš lygiai taip pat, naudojau savo pateiktą pavyzdį komercijos sistemoje, veikiančioje utf8 koduotėje.

Su sąlyga, kad šūdo nebus...

Re: banklinkai, utf-8 ir windows-1257

Susidūriau ir aš su problema, blogai veikė strlen funkcija, kai iš UTF-8 į windows-1257 perverti stringą su iconv. Todėl teko panaudot strlen(utf8_decode($string)). Gal kam pravers.