/******************************************************************************
Online C Compiler.
Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <stdio.h>
#include <iostream>
#include <string>
#include <cstring>
#define JUSTDES2_ENCIPHER 0
#define JUSTDES2_DECIPHER 1
typedef unsigned char u8bits;
typedef unsigned short u16bits;
typedef unsigned int u32bits;
typedef signed char i8bits;
typedef short i16bits;
typedef unsigned long long u64bits;
typedef long long i64bits;
static const u8bits PinKey[] = {0x01,0x02,0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12};
static const unsigned long s[64] = {
0xD8D8DBBC,0xD737D1C1,0x8B047441,0x35A9E2FE,
0x146E9560,0x8A420CFB,0xF8FBAF1F,0xC7B4DD10,
0x7A97A497,0x4CFCFA1C,0x456ADA86,0xFAC710E9,
0xE52149EF,0x338D2004,0x1E5580F1,0xE04A2F3D,
0x870A4E20,0x28BE9C1F,0x74D5E339,0x8240BD00,
0x6AA1ABC3,0x3F55E2A8,0xAF1F56BC,0x51BB11CF,
0xB7FC035E,0xE00307B0,0x08A3B44B,0x3F786D67,
0x09967CBC,0x45EB7B47,0xF3683962,0x9C14C6D2,
0x16452B42,0xADDACEBA,0x58F91ABC,0x8B68B547,
0xFAA36659,0x47BF8901,0x671AEBA9,0x30C452AB,
0x493893E1,0x72C16866,0xB7C78574,0xCD1E6B9A,
0xB6DCD49C,0x9822B7FB,0x89B07E43,0x77B78644,
0xA566F5DF,0xD22D6AC3,0xAF9A0423,0x77B71BBC,
0x81DC043E,0xC8837314,0x78659153,0xAF782C7D,
0x8C0F78A0,0x0D3095EF,0x7A506B8E,0x8445D610,
0x5223AB47,0x724C0C34,0x45AF54BC,0x38DBF9CB
};
void printhex(const u8bits *ch, u8bits *buff, int lg)
{
int i;
u8bits c;
for (i = 0; i < lg; i++)
{
c = ch[i] >> 4;
c += (c < 10)?(0x30):(0x37);
buff[2 * i] = c;
c = (ch[i] & 0x0F);
c += (c < 10)?(0x30):(0x37);
buff[(2 * i) + 1 ] = c;
}
buff[2*lg] = '\0';
}
void POIDES_cypt(int selector, const char *input, const char *key, char *output)
{
unsigned long x,c,d,r,l;
int i;
l=r=c=d=0;
i=7;
do {
x=input[i];
l = l<<1|(x&1<<0) |(x&1<<2)<<6 |(x&1<<4)<<12|(x&1<<6)<<18;
r = r<<1|(x&1<<1)>>1 |(x&1<<3)<<5 |(x&1<<5)<<11|(x&1<<7)<<17;
x = key[i];
c = c<<1|(x&1<<7)<<17|(x&1<<6)<<10|(x&1<<5)<<3 |(x&1<<4)>>4 ;
d = d<<1|(x&1<<1)<<19|(x&1<<2)<<10|(x&1<<3)<<1 ;
} while (--i>=0);
d |= c&0x0F;
c >>= 4;
i = 24;
if (selector != JUSTDES2_ENCIPHER)
goto startround;
leftby1:
c = c<<1|c>>27&1;
d = d<<1|d>>27&1;
startround:
x = s[(r>>26&62|r&1 ) ^ (c>>6 &32|c>>13&16|c>>1 &8|c>>25&4|c>>22&2|c>>14&1)]&0x00808202 ^ l;
x ^= s[(r>>23&63 ) ^ (c>>20&32|c<<4 &16|c>>10&8|c>>20&4|c>>6 &2|c>>18&1)]&0x40084010;
x ^= s[(r>>19&63 ) ^ (c &32|c>>5 &16|c>>13&8|c>>22&4|c>>1 &2|c>>20&1)]&0x04010104;
x ^= s[(r>>15&63 ) ^ (c>>7 &32|c>>17&16|c<<2 &8|c>>6 &4|c>>14&2|c>>26&1)]&0x80401040;
x ^= s[(r>>11&63 ) ^ (d>>10&32|d &16|d>>22&8|d>>17&4|d>>8 &2|d>>1 &1)]&0x21040080;
x ^= s[(r>>7 &63 ) ^ (d>>21&32|d>>12&16|d>>2 &8|d>>9 &4|d>>22&2|d>>8 &1)]&0x10202008;
x ^= s[(r>>3 &63 ) ^ (d>>7 &32|d>>3 &16|d>>14&8|d<<2 &4|d>>21&2|d>>3 &1)]&0x02100401;
x ^= s[(r&31|r>>26&32) ^ (d>>19&32|d>>6 &16|d>>11&8|d>>4 &4|d>>19&2|d>>27&1)]&0x08020820;
l=r;
r=x;
if((i&7)==0) {
i-=2;
if(selector==JUSTDES2_ENCIPHER)
goto leftby1;
c = c>>1|(c&1)<<27;
d = d>>1|(d&1)<<27;
goto startround;
}
if(i!=6) {
--i;
if(selector==JUSTDES2_ENCIPHER) {
c = c<<2|c>>26&3;
d = d<<2|d>>26&3;
goto startround;
}
else {
c = c>>2|(c&3)<<26;
d = d>>2|(d&3)<<26;
goto startround;
}
}
i = 7;
do {
*output++ = r &1<<0|r>>6 &1<<2|r>>12&1<<4|r>>18&1<<6|
l<<1 &1<<1|l>>5 &1<<3|l>>11&1<<5|l>>17&1<<7;
l >>=1;
r >>=1;
} while (--i>=0);
}
int XOR(char * input, char * h, char * output)
{
int y ;
for(y= 0; y < 8; y++) output[y] = input[y] ^ h[y];
return 0;
}
void fromhex(const char *ch, char *buff, int lg)
{
char c;
int i;
for( i = 0; i < lg; i++)
{
c = ch[2 * i];
c -= (c < 0x40)?(0x30):(0x37);
buff[i] = c << 4;
c = (ch[2 * i + 1]);
c -= (c < 0x40)?(0x30):(0x37);
buff[i] |= c;
}
}
int Crypte(const char* pin, char* pinblck , const char* uuid)
{
char pc1[8], pc2[8], pc3[16], k1[8], k2[8], tmp[20], pinky[16], result[16];
u8bits pan[16];
strcpy((char *)pan, "00");
memcpy(pan + 2, uuid, 14);
pan[16] = 0x00;
memcpy(tmp, "04", 2);
memcpy(tmp + 2, pin, 4);
memset(tmp + 6, 'F', 10);
fromhex(tmp, pc2, 8);
memset(tmp,0x00,sizeof(tmp));
memcpy(tmp, "0000", 4);
memcpy(tmp + 4, pan + strlen((char *)pan) - 13, 12);
fromhex(tmp, pc3, 8);
XOR(pc2, pc3, pc1);
memcpy(k1, PinKey, 8);
memcpy(k2, PinKey + 8, 8);
POIDES_cypt(JUSTDES2_ENCIPHER, pc1 , k1, pc2);
POIDES_cypt(JUSTDES2_DECIPHER, pc2 , k2, pc1);
POIDES_cypt(JUSTDES2_ENCIPHER, pc1 , k1, pc2);
char pinblckTmp[16];
printhex((unsigned char *)pc2, (unsigned char *)pinblckTmp, 8);
pinblckTmp[16] = 0x00;
//pinblck = McoString(pinblckTmp );
strcpy(pinblck,pinblckTmp) ;
return 0;
}
int main()
{
char pinblck[16];
std::string tuuid="046D86EA693680";
std::string pinNum = "1233";
std::string lzero ="0";
std::string paddedPin="";
for(u32bits j = 1; j < 10; j++)
{
//std::cout<<" =====>"<< atoi(pinNum.c_str()) + j <<"<======"<<std::endl;
std::string pin = std::to_string(atoi(pinNum.c_str()) + j);
//std::cout<<" pin : "<< pin.c_str() <<" len :"<<strlen(pin.c_str())<<std::endl;
if(strlen(pin.c_str()) == 3)
{
paddedPin.append(lzero);
paddedPin.append(pin);
pin = paddedPin;
}
//std::cout<<" =====>"<< lzero.c_str()<<"<======"<<std::endl;
Crypte(pin.c_str(),pinblck,tuuid.c_str());
// McoString sn,uuid,pin;
std::cout<<" uuid : "<< tuuid.c_str() <<" ; pin : "<<pin.c_str()<<" ; pinblck : "<<pinblck<<" "<<std::endl;
pin.erase();
paddedPin.erase();
}
return 0;
}
LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9ubGluZSBDIENvbXBpbGVyLgogICAgICAgICAgICAgICAgQ29kZSwgQ29tcGlsZSwgUnVuIGFuZCBEZWJ1ZyBDIHByb2dyYW0gb25saW5lLgpXcml0ZSB5b3VyIGNvZGUgaW4gdGhpcyBlZGl0b3IgYW5kIHByZXNzICJSdW4iIGJ1dHRvbiB0byBjb21waWxlIGFuZCBleGVjdXRlIGl0LgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDxjc3RyaW5nPgojZGVmaW5lIEpVU1RERVMyX0VOQ0lQSEVSIDAKI2RlZmluZSBKVVNUREVTMl9ERUNJUEhFUiAxCgp0eXBlZGVmICB1bnNpZ25lZCBjaGFyIHU4Yml0czsKdHlwZWRlZiAgdW5zaWduZWQgc2hvcnQgdTE2Yml0czsKdHlwZWRlZiB1bnNpZ25lZCBpbnQgdTMyYml0czsKdHlwZWRlZiBzaWduZWQgY2hhciBpOGJpdHM7CnR5cGVkZWYgc2hvcnQgaTE2Yml0czsKdHlwZWRlZiB1bnNpZ25lZCBsb25nIGxvbmcgdTY0Yml0czsKdHlwZWRlZiBsb25nIGxvbmcgaTY0Yml0czsKc3RhdGljIGNvbnN0IHU4Yml0cyBQaW5LZXlbXSA9IHsweDAxLDB4MDIsMHgwMywgMHgwNCwgMHgwNSwgMHgwNiwgMHgwNywgMHgwOCwgMHgwOSwgMHgwQSwgMHgwQiwgMHgwQywgMHgwRCwgMHgwRSwgMHgwRiwgMHgxMCwgMHgxMSwgMHgxMn07CnN0YXRpYyBjb25zdCB1bnNpZ25lZCBsb25nIHNbNjRdID0gewogICAgICAgIDB4RDhEOERCQkMsMHhENzM3RDFDMSwweDhCMDQ3NDQxLDB4MzVBOUUyRkUsCiAgICAgICAgMHgxNDZFOTU2MCwweDhBNDIwQ0ZCLDB4RjhGQkFGMUYsMHhDN0I0REQxMCwKCiAgICAgICAgMHg3QTk3QTQ5NywweDRDRkNGQTFDLDB4NDU2QURBODYsMHhGQUM3MTBFOSwKICAgICAgICAweEU1MjE0OUVGLDB4MzM4RDIwMDQsMHgxRTU1ODBGMSwweEUwNEEyRjNELAoKICAgICAgICAweDg3MEE0RTIwLDB4MjhCRTlDMUYsMHg3NEQ1RTMzOSwweDgyNDBCRDAwLAogICAgICAgIDB4NkFBMUFCQzMsMHgzRjU1RTJBOCwweEFGMUY1NkJDLDB4NTFCQjExQ0YsCgogICAgICAgIDB4QjdGQzAzNUUsMHhFMDAzMDdCMCwweDA4QTNCNDRCLDB4M0Y3ODZENjcsCiAgICAgICAgMHgwOTk2N0NCQywweDQ1RUI3QjQ3LDB4RjM2ODM5NjIsMHg5QzE0QzZEMiwKCiAgICAgICAgMHgxNjQ1MkI0MiwweEFEREFDRUJBLDB4NThGOTFBQkMsMHg4QjY4QjU0NywKICAgICAgICAweEZBQTM2NjU5LDB4NDdCRjg5MDEsMHg2NzFBRUJBOSwweDMwQzQ1MkFCLAoKICAgICAgICAweDQ5Mzg5M0UxLDB4NzJDMTY4NjYsMHhCN0M3ODU3NCwweENEMUU2QjlBLAogICAgICAgIDB4QjZEQ0Q0OUMsMHg5ODIyQjdGQiwweDg5QjA3RTQzLDB4NzdCNzg2NDQsCgogICAgICAgIDB4QTU2NkY1REYsMHhEMjJENkFDMywweEFGOUEwNDIzLDB4NzdCNzFCQkMsCiAgICAgICAgMHg4MURDMDQzRSwweEM4ODM3MzE0LDB4Nzg2NTkxNTMsMHhBRjc4MkM3RCwKCiAgICAgICAgMHg4QzBGNzhBMCwweDBEMzA5NUVGLDB4N0E1MDZCOEUsMHg4NDQ1RDYxMCwKICAgICAgICAweDUyMjNBQjQ3LDB4NzI0QzBDMzQsMHg0NUFGNTRCQywweDM4REJGOUNCCn07CnZvaWQgcHJpbnRoZXgoY29uc3QgdThiaXRzICpjaCwgdThiaXRzICpidWZmLCBpbnQgbGcpCnsKICAgIGludCBpOwogICAgdThiaXRzIGM7CiAgICBmb3IgKGkgPSAwOyBpIDwgbGc7IGkrKykKICAgIHsKICAgICAgICBjID0gY2hbaV0gPj4gNDsKICAgICAgICBjICs9IChjIDwgMTApPygweDMwKTooMHgzNyk7CiAgICAgICAgYnVmZlsyICogaV0gPSBjOwogICAgICAgIGMgPSAoY2hbaV0gJiAweDBGKTsKICAgICAgICBjICs9IChjIDwgMTApPygweDMwKTooMHgzNyk7CiAgICAgICAgYnVmZlsoMiAqIGkpICsgMSBdID0gYzsKICAgIH0KICAgIGJ1ZmZbMipsZ10gPSAnXDAnOwp9CnZvaWQgUE9JREVTX2N5cHQoaW50IHNlbGVjdG9yLCBjb25zdCBjaGFyICppbnB1dCwgY29uc3QgY2hhciAqa2V5LCBjaGFyICpvdXRwdXQpCnsKICAgICAgICB1bnNpZ25lZCBsb25nIHgsYyxkLHIsbDsKICAgICAgICBpbnQgaTsKICAgICAgICBsPXI9Yz1kPTA7CiAgICAgICAgaT03OwoJIGRvIHsKICAgICAgICAgICAgICAgIHg9aW5wdXRbaV07CiAgICAgICAgICAgICAgICBsID0gbDw8MXwoeCYxPDwwKSAgICB8KHgmMTw8Mik8PDYgfCh4JjE8PDQpPDwxMnwoeCYxPDw2KTw8MTg7CiAgICAgICAgICAgICAgICByID0gcjw8MXwoeCYxPDwxKT4+MSB8KHgmMTw8Myk8PDUgfCh4JjE8PDUpPDwxMXwoeCYxPDw3KTw8MTc7CiAgICAgICAgICAgICAgICB4ID0ga2V5W2ldOwogICAgICAgICAgICAgICAgYyA9IGM8PDF8KHgmMTw8Nyk8PDE3fCh4JjE8PDYpPDwxMHwoeCYxPDw1KTw8MyB8KHgmMTw8NCk+PjQgOwogICAgICAgICAgICAgICAgZCA9IGQ8PDF8KHgmMTw8MSk8PDE5fCh4JjE8PDIpPDwxMHwoeCYxPDwzKTw8MSA7CiAgICAgICAgfSB3aGlsZSAoLS1pPj0wKTsKICAgICAgICBkIHw9IGMmMHgwRjsKICAgICAgICBjID4+PSA0OwogICAgICAgIGkgPSAyNDsKICAgICAgICBpZiAoc2VsZWN0b3IgIT0gSlVTVERFUzJfRU5DSVBIRVIpCiAgICAgICAgICAgICAgICBnb3RvIHN0YXJ0cm91bmQ7CmxlZnRieTE6CiAgICAgICAgYyA9IGM8PDF8Yz4+MjcmMTsKICAgICAgICBkID0gZDw8MXxkPj4yNyYxOwpzdGFydHJvdW5kOgogICAgICAgIHggID0gc1socj4+MjYmNjJ8ciYxICkgXiAoYz4+NiAmMzJ8Yz4+MTMmMTZ8Yz4+MSAmOHxjPj4yNSY0fGM+PjIyJjJ8Yz4+MTQmMSldJjB4MDA4MDgyMDIgXiBsOwogICAgICAgIHggXj0gc1socj4+MjMmNjMgICAgICkgXiAoYz4+MjAmMzJ8Yzw8NCAmMTZ8Yz4+MTAmOHxjPj4yMCY0fGM+PjYgJjJ8Yz4+MTgmMSldJjB4NDAwODQwMTA7CiAgICAgICAgeCBePSBzWyhyPj4xOSY2MyAgICAgKSBeIChjICAgICYzMnxjPj41ICYxNnxjPj4xMyY4fGM+PjIyJjR8Yz4+MSAmMnxjPj4yMCYxKV0mMHgwNDAxMDEwNDsKICAgICAgICB4IF49IHNbKHI+PjE1JjYzICAgICApIF4gKGM+PjcgJjMyfGM+PjE3JjE2fGM8PDIgJjh8Yz4+NiAmNHxjPj4xNCYyfGM+PjI2JjEpXSYweDgwNDAxMDQwOwogICAgICAgIHggXj0gc1socj4+MTEmNjMgICAgICkgXiAoZD4+MTAmMzJ8ZCAgICAmMTZ8ZD4+MjImOHxkPj4xNyY0fGQ+PjggJjJ8ZD4+MSAmMSldJjB4MjEwNDAwODA7CiAgICAgICAgeCBePSBzWyhyPj43ICY2MyAgICAgKSBeIChkPj4yMSYzMnxkPj4xMiYxNnxkPj4yICY4fGQ+PjkgJjR8ZD4+MjImMnxkPj44ICYxKV0mMHgxMDIwMjAwODsKICAgICAgICB4IF49IHNbKHI+PjMgJjYzICAgICApIF4gKGQ+PjcgJjMyfGQ+PjMgJjE2fGQ+PjE0Jjh8ZDw8MiAmNHxkPj4yMSYyfGQ+PjMgJjEpXSYweDAyMTAwNDAxOwogICAgICAgIHggXj0gc1sociYzMXxyPj4yNiYzMikgXiAoZD4+MTkmMzJ8ZD4+NiAmMTZ8ZD4+MTEmOHxkPj40ICY0fGQ+PjE5JjJ8ZD4+MjcmMSldJjB4MDgwMjA4MjA7CiAgICAgICAgbD1yOwogICAgICAgIHI9eDsKCiAgICAgICAgaWYoKGkmNyk9PTApIHsKICAgICAgICAgICAgICAgIGktPTI7CiAgICAgICAgICAgICAgICBpZihzZWxlY3Rvcj09SlVTVERFUzJfRU5DSVBIRVIpCiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gbGVmdGJ5MTsKICAgICAgICAgICAgICAgIGMgPSBjPj4xfChjJjEpPDwyNzsKICAgICAgICAgICAgICAgIGQgPSBkPj4xfChkJjEpPDwyNzsKICAgICAgICAgICAgICAgIGdvdG8gc3RhcnRyb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICBpZihpIT02KSB7CiAgICAgICAgICAgICAgICAtLWk7CiAgICAgICAgICAgICAgICBpZihzZWxlY3Rvcj09SlVTVERFUzJfRU5DSVBIRVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYyA9IGM8PDJ8Yz4+MjYmMzsKICAgICAgICAgICAgICAgICAgICAgICAgZCA9IGQ8PDJ8ZD4+MjYmMzsKICAgICAgICAgICAgICAgICAgICAgICAgZ290byBzdGFydHJvdW5kOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgYyA9IGM+PjJ8KGMmMyk8PDI2OwogICAgICAgICAgICAgICAgICAgICAgICBkID0gZD4+MnwoZCYzKTw8MjY7CiAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gc3RhcnRyb3VuZDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgIGkgPSA3OwogICAgICAgIGRvIHsKICAgICAgICAgICAgICAgICpvdXRwdXQrKyA9IHIgICAgJjE8PDB8cj4+NiAmMTw8MnxyPj4xMiYxPDw0fHI+PjE4JjE8PDZ8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsPDwxICYxPDwxfGw+PjUgJjE8PDN8bD4+MTEmMTw8NXxsPj4xNyYxPDw3OwogICAgICAgICAgICAgICAgbCA+Pj0xOwogICAgICAgICAgICAgICAgciA+Pj0xOwoJfSB3aGlsZSAoLS1pPj0wKTsKfQoKaW50IFhPUihjaGFyICogaW5wdXQsIGNoYXIgKiBoLCBjaGFyICogb3V0cHV0KQp7CiAgICAgICAgaW50IHkgOwogICAgICAgIGZvcih5PSAwOyB5IDwgODsgeSsrKSBvdXRwdXRbeV0gPSBpbnB1dFt5XSBeIGhbeV07CiAgICAgICAgcmV0dXJuIDA7Cn0Kdm9pZCBmcm9taGV4KGNvbnN0IGNoYXIgKmNoLCBjaGFyICpidWZmLCBpbnQgbGcpCnsKICAgIGNoYXIgYzsKICAgIGludCBpOwogICAgZm9yKCBpID0gMDsgaSA8IGxnOyBpKyspCiAgICB7CiAgICAgICAgYyA9IGNoWzIgKiBpXTsKICAgICAgICBjIC09IChjIDwgMHg0MCk/KDB4MzApOigweDM3KTsKICAgICAgICBidWZmW2ldID0gYyA8PCA0OwogICAgICAgIGMgPSAoY2hbMiAqIGkgKyAxXSk7CiAgICAgICAgYyAtPSAoYyA8IDB4NDApPygweDMwKTooMHgzNyk7CiAgICAgICAgYnVmZltpXSB8PSBjOwogICAgfQp9CmludCBDcnlwdGUoY29uc3QgY2hhciogcGluLCAgY2hhciogcGluYmxjayAsIGNvbnN0IGNoYXIqIHV1aWQpCnsKCWNoYXIgcGMxWzhdLCBwYzJbOF0sIHBjM1sxNl0sIGsxWzhdLCBrMls4XSwgdG1wWzIwXSwgIHBpbmt5WzE2XSwgcmVzdWx0WzE2XTsKICAgICAgICB1OGJpdHMgIHBhblsxNl07CiAgICAgICAgc3RyY3B5KChjaGFyICopcGFuLCAiMDAiKTsKICAgICAgICBtZW1jcHkocGFuICsgMiwgdXVpZCwgMTQpOwogICAgICAgIHBhblsxNl0gPSAweDAwOwogICAgICAgIG1lbWNweSh0bXAsICIwNCIsIDIpOwogICAgICAgIG1lbWNweSh0bXAgKyAyLCBwaW4sIDQpOwogICAgICAgIG1lbXNldCh0bXAgKyA2LCAnRicsIDEwKTsKICAgICAgICBmcm9taGV4KHRtcCwgcGMyLCA4KTsKICAgICAgICBtZW1zZXQodG1wLDB4MDAsc2l6ZW9mKHRtcCkpOwogICAgICAgIG1lbWNweSh0bXAsICIwMDAwIiwgNCk7CiAgICAgICAgbWVtY3B5KHRtcCArIDQsIHBhbiArIHN0cmxlbigoY2hhciAqKXBhbikgLSAxMywgMTIpOwoJZnJvbWhleCh0bXAsIHBjMywgOCk7CiAgICAgICAgWE9SKHBjMiwgcGMzLCBwYzEpOwogICAgICAgIG1lbWNweShrMSwgUGluS2V5LCA4KTsKCW1lbWNweShrMiwgUGluS2V5ICsgOCwgOCk7CgoJUE9JREVTX2N5cHQoSlVTVERFUzJfRU5DSVBIRVIsIHBjMSAsIGsxLCBwYzIpOwoJUE9JREVTX2N5cHQoSlVTVERFUzJfREVDSVBIRVIsIHBjMiAsIGsyLCBwYzEpOwoJUE9JREVTX2N5cHQoSlVTVERFUzJfRU5DSVBIRVIsIHBjMSAsIGsxLCBwYzIpOwoJY2hhciBwaW5ibGNrVG1wWzE2XTsKICAgICAgICBwcmludGhleCgodW5zaWduZWQgY2hhciAqKXBjMiwgKHVuc2lnbmVkIGNoYXIgKilwaW5ibGNrVG1wLCA4KTsKCXBpbmJsY2tUbXBbMTZdID0gMHgwMDsKCS8vcGluYmxjayA9IE1jb1N0cmluZyhwaW5ibGNrVG1wICk7CiAgICBzdHJjcHkocGluYmxjayxwaW5ibGNrVG1wKSA7ICAKICAgICAgICByZXR1cm4gMDsKCiAgCn0KaW50IG1haW4oKQp7CiAgICBjaGFyIHBpbmJsY2tbMTZdOwoJc3RkOjpzdHJpbmcgdHV1aWQ9IjA0NkQ4NkVBNjkzNjgwIjsKCXN0ZDo6c3RyaW5nIHBpbk51bSA9ICIxMjMzIjsKCXN0ZDo6c3RyaW5nIGx6ZXJvID0iMCI7CglzdGQ6OnN0cmluZyBwYWRkZWRQaW49IiI7Cglmb3IodTMyYml0cyBqID0gMTsgaiA8IDEwOyBqKyspCgl7CgkgICAgCgkgICAgLy9zdGQ6OmNvdXQ8PCIgPT09PT0+Ijw8IGF0b2kocGluTnVtLmNfc3RyKCkpICsgaiA8PCI8PT09PT09Ijw8c3RkOjplbmRsOwoJICAgc3RkOjpzdHJpbmcgcGluID0gc3RkOjp0b19zdHJpbmcoYXRvaShwaW5OdW0uY19zdHIoKSkgKyBqKTsKCSAgIC8vc3RkOjpjb3V0PDwiIHBpbiA6ICI8PCBwaW4uY19zdHIoKSA8PCIgbGVuIDoiPDxzdHJsZW4ocGluLmNfc3RyKCkpPDxzdGQ6OmVuZGw7CgkgICBpZihzdHJsZW4ocGluLmNfc3RyKCkpID09IDMpIAoJICAgewoJICAgICAgIHBhZGRlZFBpbi5hcHBlbmQobHplcm8pOwoJICAgICAgIHBhZGRlZFBpbi5hcHBlbmQocGluKTsKCSAgICAgICBwaW4gPSBwYWRkZWRQaW47CgkgICB9CgkgIC8vc3RkOjpjb3V0PDwiID09PT09PiI8PCBsemVyby5jX3N0cigpPDwiPD09PT09PSI8PHN0ZDo6ZW5kbDsKCQlDcnlwdGUocGluLmNfc3RyKCkscGluYmxjayx0dXVpZC5jX3N0cigpKTsKCS8vCU1jb1N0cmluZyBzbix1dWlkLHBpbjsKCQlzdGQ6OmNvdXQ8PCIgdXVpZCA6ICI8PCB0dXVpZC5jX3N0cigpIDw8IiA7IHBpbiA6ICI8PHBpbi5jX3N0cigpPDwiIDsgcGluYmxjayA6ICI8PHBpbmJsY2s8PCIgIjw8c3RkOjplbmRsOwoJCXBpbi5lcmFzZSgpOwoJCXBhZGRlZFBpbi5lcmFzZSgpOwoJfQoKICAgIHJldHVybiAwOwp9Cg==