Odkodowywanie Aztec Code 2D - Dowody Rejestracyjne, algorytm nrv2e, darmowy kod

Odpowiedz Nowy wątek
2018-07-08 14:52
Rev
22

Jeżeli zastanawialiście się kiedyś co zawiera kod graficzny na dowodach rejestracyjnych waszych pojazdów to jest to Aztec Code. Zdekodowanie go da dane (jeszcze po base64), które są dodatkowo skompresowane, ale można je przekształcić do postaci tekstowej za pomocą poniższego kodu.

import base64
from ctypes import *

code = 'BgQAANtYAAJDAPkxAHwAQXIw7zcGNN4ANiox+w81HrUGOP8eUABSAEUA+1oAWQBEDv9OAFQAIABN3wAuClMAvlQPV/eKUhq9Wg5X7k58Utc' \
       'WSVq9TF5J79pBZ+5PAEsG12bTSm5GVQBM/ntSAEH7L1dj+0MAS1vvMvovewo3Ut4wDi39HjEAN6Pbl0FNe3YgPt5Q3kv3IlSevVnX1z9FMm' \
       'uCShL2WgBaG9umKADvSAApJnx75k+itwZMAEx9X0rvbkSOTXtOOF/DRy0WOW53fPYLFoMzLr0xAi3DGnevLQOCfJ/vQZ5TcBZrN0oa9k4Af' \
       'A82Q4QaDzj3q8deN6sN7zIE/1x8lbMnQdwBQi5ZT86jL2tqNAr2MwAw34xSH+uPSVPYFxZThBMzON8AMJM5wQA3MwRcMX7bNcET2jInwyed' \
       'E01HZ4dlM94qKy0DL38fNgAqeBszSxOvNIeKfHM7fCLxNQAwVkMtdzl7Xiw/YMyrFzxQACBWw+Hza7c3C93/NWuHg1OWRquPQ5KP02K9IBZ' \
       'T4QZC9oNZU7aXFiOX83U4ADJFC7ADhrNVCyOW8w9qMbEnZhdHbHxjdjIT7E4DW0M3OQuGaxYmCSSSSSr/'

ucl = cdll.LoadLibrary('libucl.so')
ucl.ucl_nrv2e_decompress_safe_8.argtypes = (c_char_p, c_int32, POINTER(c_char), POINTER(c_int32), c_void_p)
ucl.ucl_nrv2e_decompress_safe_8.restype = c_int32

data = base64.b64decode(code)

size = int.from_bytes(data[:4], byteorder='little')

buffer = (c_char * size)()
buffer_length = c_int32(size)

ucl.ucl_nrv2e_decompress_safe_8(data[4:], len(data), buffer, buffer_length, None)

result = bytes(buffer).decode('utf-16')

print(result)

Co dla przykładowego kodu daje wynik XXC1|AAA0007046|1465058|PREZYDENT M. ST. WARSZAWY|DZIELNICA MOKOTÓW|UL. RAKOWIECKA 25/27|02-517 WARSZAWA|DMI 1PNK|TOYOTA|E12J|ZZE120(H)||COROLLA|JTDKM28E100089120|2013-11-06|---|KOWALSKI JAN|JAN|KOWALSKI||82091711022|02-517|WARSZAWA||WAŁBRZYSKA|24|30|KOWALSKA MARIA|MARIA|KOWALSKA||88030971022|02-517|WARSZAWA||WAŁBRZYSKA|24|30|1655|1655|2655|1205|M1|e11*2001/116*0180*04|2|1000|450|---|1398,00|71,00|P |2005-07-01|5|---|SAMOCHÓD OSOBOWY|---|2005|---|8,82|AAA0000000|02650008000158|03|02|000|2000NNNNNNNN|009002001|.

Kod w Pythonie wykorzystuje bibliotekę libucl. Na Ubuntu i Debianie wystarczy zrobić sudo apt-get install libucl-dev.

Kod wypuszczam na licencji GPL 2.


edytowany 9x, ostatnio: Rev, 2018-07-13 01:08
Specjalnie po roku się zalogowałem żeby dać Ci plusa, jak zobaczyłem aferę o tym kodzie na wypoku. :-D - Endrju 2018-07-08 22:04
Tu macie wersję dla Pythona z rozpoznawaniem obrazu https://pypi.org/project/aztecdecoder/ :) - Bartosz Wójcik 2018-07-13 16:42
Ten kod to prosty pythonowy wrapper na bazie ctypes na oryginalną bibliotekę ucl wydaną na licencji GPL2. Nie możesz nawet gdybyś chciał wypuścić tego kodu z inną licencją bo GPL 2 to licencja wirusowa. -.- - siloam 2019-01-12 19:15
iii uwaga... dlatego tego nie zrobiłem! - Rev 2019-01-13 14:23

Pozostało 580 znaków

2018-07-13 12:45
Rev
1

No mi jeszcze brakuje, żeby @Bartosz Wójcik przyszedł i dał linki do swoich płatnych pseudolibów w tym wątku :D.


edytowany 1x, ostatnio: Rev, 2018-07-13 12:45
nie wywołuj wilka z lasu bo przylezie i się przyiwani że dyskryminujemy kobiety... :D - kate87 2018-07-13 13:06
Hehe dobra afera nie jest zła :) - Bartosz Wójcik 2018-07-13 16:37
@Bartosz Wójcik: ano dobra afera. Zalecam poczytać sobie teraz coś na temat fake DMCA notice consequences :) - Shalom 2018-07-13 16:52
Mówiłam ze przylezie.. - kate87 2018-07-13 18:46

Pozostało 580 znaków

2018-07-16 01:37
1

No dobra, a czemu nie ma żadnej stronki .gov, która by to robiła, tylko trzeba się bawić w jakieś 3rd party?

edytowany 1x, ostatnio: WeiXiao, 2018-07-16 01:38
bo #polskawstajezkolan ;) - Shalom 2018-07-16 09:15

Pozostało 580 znaków

2018-07-16 09:47
0

Dobre pytanie, fajnie jakby PWPW, które umieszcza kod na dowodach się wypowiedziało na ten temat ;) Wysyłając do nich oficjalne zapytanie dostałem tylko informację, że mogą mi udostępnić odpłatnie, za nie małe pieniądze, swoją bibliotekę. Dodam, że licencję dają tylko na rok i ich biblioteka nie umożliwia dekodowanie danych osobowych :) W takim państwie żyjemy, oceń to sam.

Polecam przeczytać dwa wątki na wykopie na ten temat (Google wykop aztec)

Pozostało 580 znaków

2018-08-01 18:48
Rev
4

Na z3s pojawił się artykuł o całej sprawie: https://zaufanatrzeciastrona.[...]erze-aztec-i-pewnym-monopolu/.


Pozostało 580 znaków

2018-10-25 16:28
0

ma ktoś może to w php?:) Mam kod pobranu z Azteca (zdekodowany) i muszę go "rozszyfrować":
hQMAANtYAAJDAP8xAHwAQgBBAL9NEjQAMN8AMwI5AL03KjLaAiY1/RJTAFT7QlIATxN/IABXAEX9AEoASABF9ytXLu9LAElSdfcAbAAugr8gnkEASn1XNO8uOAotfp4wADDVe91PQq8CRy+9IPpF7u4wIt16VQBE7K8DtR427wpXL71aA66qQtrXCk5euzJyBl43c+vTMVr3LQAw87UKOO8qLQNuDlAARQuP2kEBkkv3ElOWsXwbbEswfFx/MT4jNf6XOQAxCK8w4Gfgj1eSTHvBRattI0h1g1L2qnsBBr5D23wf2zHBADYzBQcyfcs1gxMMny5D7TYANCNsDzYyO+Iw8Cs3dkdvBBlfrTosP7AXPEQAIFaPjCctgznbAC3vYPdoU/B3T2Nir57Ta0ZLg0+/gq6CWRcNlpf/BzEAgiwn70EDaxY4BsszdCswH9s0ALcwdzBrA7Z8m8ILwifMA06FszM5fAs3tODzkkkkkqD/AA==C

Pozostało 580 znaków

2018-11-01 17:53
0
lukmopy napisał(a):

ma ktoś może to w php?:) Mam kod pobranu z Azteca (zdekodowany) i muszę go "rozszyfrować":
hQMAANtYAAJDAP8xAHwAQgBBAL9NEjQAMN8AMwI5AL03KjLaAiY1/RJTAFT7QlIATxN/IABXAEX9AEoASABF9ytXLu9LAElSdfcAbAAugr8gnkEASn1XNO8uOAotfp4wADDVe91PQq8CRy+9IPpF7u4wIt16VQBE7K8DtR427wpXL71aA66qQtrXCk5euzJyBl43c+vTMVr3LQAw87UKOO8qLQNuDlAARQuP2kEBkkv3ElOWsXwbbEswfFx/MT4jNf6XOQAxCK8w4Gfgj1eSTHvBRattI0h1g1L2qnsBBr5D23wf2zHBADYzBQcyfcs1gxMMny5D7TYANCNsDzYyO+Iw8Cs3dkdvBBlfrTosP7AXPEQAIFaPjCctgznbAC3vYPdoU/B3T2Nir57Ta0ZLg0+/gq6CWRcNlpf/BzEAgiwn70EDaxY4BsszdCswH9s0ALcwdzBrA7Z8m8ILwifMA06FszM5fAs3tODzkkkkkqD/AA==C

Nie wiem czy RODO pozwala na umieszczanie danych osobowych z tego "rozszyfrowanego" kodu. Dlatego nie pokażę co tam jest.

Pozostało 580 znaków

2019-01-04 21:42
3

free_source_code.jpg

Ode mnie dwa kody:

C#.NET Otwarta implementacja dekodera Aztec z dowodów rejestracyjnych

/*
 * C#.NET implementation of NRV2E decompression algorithm
 * - by http://haker.info A.D. 2019
 * Based on original UCL library written by:
 * Markus F.X.J. Oberhumer <[email protected]>
 * http://www.oberhumer.com/opensource/ucl/
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
*/

using System;
using System.Text;

namespace FreeAztecVehicleDocDecoder
{
    public class VehicleDocumentAztecDecoder
    {
        private const int START_OFFSET = 4;
        private byte[] src;
        private int ilen = START_OFFSET;
        private int currentByte;
        private int currentBit;
        private byte[] dst;

        public string Decode(string text)
        {
            byte[] decoded = Base64Decode(text);
            byte[] decompressed = DecompressNRV2E(decoded);
            return Encoding.Unicode.GetString(decompressed);
        }

        private byte[] DecompressNRV2E(byte[] sourceData)
        {
            src = sourceData;

            uint olen = 0, last_m_off = 1;

            dst = new byte[BitConverter.ToInt32(src, 0)];

            while (ilen < src.Length)
            {
                uint m_off, m_len;

                while (GetBit() == 1)
                {
                    dst[olen++] = src[ilen++];
                }

                m_off = 1;
                while (true)
                {
                    m_off = m_off * 2 + GetBit();
                    if (GetBit() == 1) break;
                    m_off = (m_off - 1) * 2 + GetBit();
                }

                if (m_off == 2)
                {
                    m_off = last_m_off;
                    m_len = GetBit();
                }
                else
                {
                    m_off = (m_off - 3) * 256 + src[ilen++];
                    if (m_off == 0xffffffff)
                        break;
                    m_len = (m_off ^ 0xffffffff) & 1;
                    m_off >>= 1;
                    last_m_off = ++m_off;
                }
                if (m_len > 0)
                    m_len = (uint)1 + GetBit();
                else if (GetBit() == 1)
                    m_len = (uint)3 + GetBit();
                else
                {
                    m_len++;
                    do
                    {
                        m_len = m_len * 2 + GetBit();
                    } while (GetBit() == 0);
                    m_len += 3;
                }
                m_len += (uint)(m_off > 0x500 ? 1 : 0);

                uint m_pos;
                m_pos = olen - m_off;

                dst[olen++] = dst[m_pos++];
                do dst[olen++] = dst[m_pos++]; while (--m_len > 0);
            }
            return dst;
        }

        private byte GetBit()
        {
            if (ilen >= src.Length)
                throw new Exception("Przesunięcie jest poza zakresem.");

            if (currentBit == 0)
            {
                currentByte = src[ilen++];
                currentBit = 8;
            }

            return (byte)(((uint)currentByte >> --currentBit) & 1);
        }

        private byte[] Base64Decode(string textToDecode)
        {
            if (string.IsNullOrWhiteSpace(textToDecode)) return new byte[0];

            if (textToDecode.Length % 2 == 1)
            {
                textToDecode = textToDecode.Substring(0, textToDecode.Length - 1);
            }

            return Convert.FromBase64String(textToDecode);
        }
    }
}

C++ Otwarta implementacja dekodera Aztec z dowodów rejestracyjnych

/*
* C++ implementation of NRV2E decompression algorithm
* which was used in this project to decode
* Aztec 2D from Polish Vehicle Registration Documents
* - by http://haker.info A.D. 2019
*
* Based on original UCL library written by:
* Markus F.X.J. Oberhumer <[email protected]>
* http://www.oberhumer.com/opensource/ucl/
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include <iostream>
#include <string>
#include <vector>

const int START_OFFSET = 4;
std::vector<unsigned char> src;
int ilen = START_OFFSET;
int currentByte;
int currentBit;

static unsigned char GetBit()
{
    if (ilen >= src.size())
        throw std::invalid_argument("Przesunięcie jest poza zakresem.");

    if (currentBit == 0)
    {
        currentByte = src[ilen++];
        currentBit = 8;
    }

    return (unsigned char)(((unsigned int)currentByte >> --currentBit) & 1);
}

static std::vector<unsigned char> DecompressNRV2E(std::vector<unsigned char> sourceData)
{
    src = sourceData;

    int destSize = src[0] | (int)src[1] << 8 | (int)src[2] << 16 | (int)src[3] << 24;
    std::vector<unsigned char> dst(destSize);

    unsigned int olen = 0, last_m_off = 1;

    while (ilen < src.size())
    {
        unsigned int m_off, m_len;

        while (GetBit() == 1)
        {
            dst[olen++] = src[ilen++];
        }

        m_off = 1;
        while (true)
        {
            m_off = m_off * 2 + GetBit();
            if (GetBit() == 1) break;
            m_off = (m_off - 1) * 2 + GetBit();
        }

        if (m_off == 2)
        {
            m_off = last_m_off;
            m_len = GetBit();
        }
        else
        {
            m_off = (m_off - 3) * 256 + src[ilen++];
            if (m_off == 0xffffffff)
                break;
            m_len = (m_off ^ 0xffffffff) & 1;
            m_off >>= 1;
            last_m_off = ++m_off;
        }
        if (m_len > 0)
            m_len = (unsigned int)1 + GetBit();
        else if (GetBit() == 1)
            m_len = (unsigned int)3 + GetBit();
        else
        {
            m_len++;
            do
            {
                m_len = m_len * 2 + GetBit();
            } while (GetBit() == 0);
            m_len += 3;
        }
        m_len += (unsigned int)(m_off > 0x500 ? 1 : 0);

        unsigned int m_pos;
        m_pos = olen - m_off;

        dst[olen++] = dst[m_pos++];
        do dst[olen++] = dst[m_pos++]; while (--m_len > 0);
    }
    return dst;
}

static std::string base64_decode(const std::string &in) {

    std::string out;

    std::vector<int> T(256, -1);
    for (int i = 0; i < 64; i++)
        T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;

    int val = 0, valb = -8;
    for (unsigned char c : in)
    {
        if (T[c] == -1) break;
        val = (val << 6) + T[c];
        valb += 6;
        if (valb >= 0)
        {
            out.push_back(char((val >> valb) & 0xFF));
            valb -= 8;
        }
    }
    return out;
}

int main(int argc, char *argv[])
{
    std::string test1 = "BgQAANtYAAJDAPkxAHwAQXIw7zcGNN4ANiox+w81HrUGOP8eUABSAEUA+1oAWQBEDv9OAFQAIABN3wAuClMAvlQPV/eKUhq9Wg5X7k58UtcWSVq9TF5J79pBZ+5PAEsG12bTSm5GVQBM/ntSAEH7L1dj+0MAS1vvMvovewo3Ut4wDi39HjEAN6Pbl0FNe3YgPt5Q3kv3IlSevVnX1z9FMmuCShL2WgBaG9umKADvSAApJnx75k+itwZMAEx9X0rvbkSOTXtOOF/DRy0WOW53fPYLFoMzLr0xAi3DGnevLQOCfJ/vQZ5TcBZrN0oa9k4AfA82Q4QaDzj3q8deN6sN7zIE/1x8lbMnQdwBQi5ZT86jL2tqNAr2MwAw34xSH+uPSVPYFxZThBMzON8AMJM5wQA3MwRcMX7bNcET2jInwyedE01HZ4dlM94qKy0DL38fNgAqeBszSxOvNIeKfHM7fCLxNQAwVkMtdzl7Xiw/YMyrFzxQACBWw+Hza7c3C93/NWuHg1OWRquPQ5KP02K9IBZT4QZC9oNZU7aXFiOX83U4ADJFC7ADhrNVCyOW8w9qMbEnZhdHbHxjdjIT7E4DW0M3OQuGaxYmCSSSSSr/";

    if (test1.length() % 2 == 1)
    {
        test1[test1.length() - 1] = '\0';
    }

    std::string decoded = base64_decode(test1);
    std::vector<unsigned char> decodedVec = std::vector<unsigned char>(decoded.begin(), decoded.end());

    std::vector<unsigned char> decompressed = DecompressNRV2E(decodedVec);

    std::wstring plainData(decompressed.begin(), decompressed.end());

    std::wcout << plainData << std::endl;

#if _DEBUG
    getchar();
#endif

    return EXIT_SUCCESS;
}

Pozdrawiam.

Pozostało 580 znaków

2019-07-01 23:19
0

Ok. Ja natomiast głowię się jak zaszyfrować dane do AZTEC - takiego jak w dow. rej.
Przychodzi mi do głowy jedynie odwrócenie kolejności (załącznik). Czyli tekst do NRV2E --> Base64 --> Graficzny kod AZTEC
Jakieś pomysły?

Pozdrawiam,
Roberto

edytowany 2x, ostatnio: Robo159, 2019-07-01 23:22

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0