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

23

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.

2

Poniższy kod oraz opis podlegają licencji LGPL.

Ale nie ma nagłówka z licencją, opisującego kto napisał program :]

0

Zapytam szofera czy ma takie coś i sprawdzę czy działa, dzięki.

0

Dorzuciłem brakujący plik nagłówkowy.

0

panie Ferdku afera jest

Jakoś w ogóle nie zajarzyłem, że tu jest afera jakaś, więc tak dla kontekstu:

GitHub zablokował repozytorium z tym dekoderem, na wiosek DMCA firmy powiedzmy znanej.

W wątku na Wykopie pojawiła się wspomniana firma, reklamując swoją implementację w postaci WebAPI (BTW: jakiś dziwny ten C#)

0

Ich usługa to SaaS, publicznie dostępne są tylko web API. Jakim cudem ktoś niby ukradł implementację?

Ciekawe jak wyglądają konsekwencje za fałszywe DMCA i czy to podpada pod fałszywe zeznania.

2

Z tego co PELock pisze to sugeruje ze gość zrobił RE jego dll. WebApi na końcu ma jakieś dll. Może faktycznie ktoś dostał to w swoje łapki? Jeśli tak to nie dziwie się PELock. Jeśli z kolei to alternatywna implrmentacja na podstawie dokumentacji to nie widzę problemu. Dziwi mnie jedno - gość nie pamięta jaka bibliotekę maglowal na RE i skąd ja miał. No ten kod jest osiągnięciem i jeszcze afera wyszła wiec jest conajmniej dziwne ze ze pamięta. No ale wykop wylał hejt na prywaciarza jak śmie mieć kod własnościowy, za kase etc. Nawet ktoś stwierdził ze skoro państwowe to musi być OS...

1

Z tego co PELock pisze to sugeruje ze gość zrobił RE jego dll.

Pytanie, czy ma na to jakiekolwiek dowody? Bo generalnie we współczesnym świecie istnieje taka śmieszna zasada, co się zowie "domniemanie niewinności"...

Dziwi mnie jedno - gość nie pamięta jaka bibliotekę maglowal na RE i skąd ja miał.

Ja też nie pamiętam, z jakich bibliotek korzystałam w moich pobocznych projektach 5 lat temu. Właściwie to nawet nie pamiętam nawet nazw wszystkich moich pobocznych projektów... Nie widzę w tym nic dziwnego.

0

Z tego co PELock pisze to sugeruje ze gość zrobił RE jego dll. WebApi na końcu ma jakieś dll. Może faktycznie ktoś dostał to w swoje łapki?

API webowe działa w taki sposób, że przesyła dane na serwer, całe dekodowanie odbywa się na serwerze i otrzymujesz wynik z powrotem. Jakim cudem gość zreversował DLLkę znajdującą się na cudzym serwerze?

Nie oceniam zachowania samego gościa, ale czy faktycznie tak powinno być, że żeby odczytać państwowy dokument musisz kupić zamkniętą DLLkę od Polskiej Wytwórni Papierów Wartosciowych? To jest kręcenie biznesu w oparciu o monopol.

1

@aurel:

Wiesz winę należy udowodnić. Masz racę. Nikt też nie udowodnił, że PELock kłamie ;) Mówię dziwne - bo jednak to ważny projekt i dlaczego nie zostawił sobie tej dll której robił RE koło kodu? Może to zwykłe niedbalstwo, a może celowo "nie ma" już tej dll. Słowo przeciwko słowu, chyba, że wejdzie to na ścieżkę sądową - my pewnie się już nie dowiemy. Zastanawia mnie, natomiast dlaczego wszyscy zakładają, że PELock chce uwalić ten darmowy kod, z powodów, ze to konkurencja. Może tak być, ale nie musi. Niestety pokutuje etos hakera który walczy z systemem i udostępnia to co powinno być darmowe i wolne. Okazuje się często, że takie praktyki to nic innego jak kradzież czy łamanie praw autorskich. Mówię o tym, bo widzę znaczną asymetrię opinii na wykopie. Nawet są ludzie co de facto ignorują fakt, że może to naruszać prawo, a i tak sądzą, że "oprogramowanie do obsługi państwowych rzeczy powinno być wolne" - ale skoro nie jest, ktoś dogadał się z państwem to jest zamknięte i tyle. Powtarzam, że nie wiem jak jest na prawdę, ale zaznaczam, że tutaj nie można jednoznacznie obrać strony bo mamy tylko krzyki z dwóch stron i zero faktów, poza tym, ze GH usunął repo więc jakieś podstawy musiał mieć.

1

@somedev

  1. Bart zapracował sobie na odpowiednią opinię w środowisku, stąd też wszyscy z góry założyli jak wygląda sytuacja
  2. Bart nie miał żadnej umowy z PWPW ani związku z tym projektem, po prostu zreversował ich bibliotekę a teraz próbuje zrobić monopol na dekoder
  3. GH usunęło repo z automatu tak samo jak jest z filmikami na youtbe czy profilami na facebooku. Wystarczy ze ktoś zaraportuje, a potem najwyżej się to cofnie. W tym przypadku jednak takie zgłoszenie może mieć spore konsekwencje i nie zdziwi mnie jak Bart niedługo zacznie twittować z jakiegoś guantanamo albo innego sztumu...
0

1 Nie wiem co tam kolega nawywijał. Z tego co znalazłem to tylko to https://www.wykop.pl/link/3396923/obfuskacja-zaciemnianie-kodow-zrodlowych-skryptow-autoit/. Niemniej to też nieporozumienie, bo PELock oczekiwał odwrotnego działania co do jego programu, a gość nieco obszedł system. Jeszcze w temacie Azteca też się wypowiadał. Wiem, że ten "wygrany" chciał pokazać, że jak robi się RE to nie odczytuje się całego kodu etc. ale zasady konkursu były jasne. Inna sprawa, że trzeba było napisać swój skrypt który nie był w sieci to by afery nie było. Co do innych rzeczy to serio nic nie słyszałem o tym Panu (PELock).
2 Rozumiem. Myślałem, że on dostarczył w porozumieniu z PWPW oprogramowanie, a dodatkowo sprzedaje usługi. Mówisz, że zrobił RE biblioteki z PWPW? No to pachnie, że złodziej okradł złodzieja, ale cii.. bo znów ktoś oskarży mnie o oskarżanie innych ;)
3 Ah rozumiem. Nie wiedziałem, że tak łatwo usunąć konto z takich serwisów. Ale serio fałszywe oskarżenie i to nie przed sądem, a prywatną firma jaką jest GH grozi takimi konsekwencjami? A jeżeli ktoś prostu zgłosił, że podejrzewa, że dane repo jest w części zapełnione kodem od niego ukradzionym?

0

Ale serio fałszywe oskarżenie i to nie przed sądem, a prywatną firma jaką jest GH grozi takimi konsekwencjami?

To nie jest jakieś tam raportowanie do githuba. To jest skarga w oparciu o https://en.wikipedia.org/wiki/Digital_Millennium_Copyright_Act a to jest poważna sprawa i za fałszywe oskarżenia z tego tytułu grożą grzywny rzędu 150k USD albo więzienie.

1

Ale serio fałszywe oskarżenie i to nie przed sądem, a prywatną firma jaką jest GH grozi takimi konsekwencjami?

Jakimiż to strasznymi konsekwencjami? Jedyna konsekwencja jest taka, że usunięto mu repo z ich prywatnej strony. Każda prywatna firma może robić na swojej prywatnej stronie co jej się żywnie podoba, a jak komuś nie podoba się polityka firmy, to może skorzystać z innej firmy. Tak też tu się stało - kod został przeniesiony na gitlab i parę innych.

1

Jest już alternatywna implementacja https://github.com/dex4er/drpdecompress. Dane były skompresowane algorytmem NRV2E.

0

Czy potrafi ktoś to przerobić na biblioteke C# pod WPF ?

2

Ponieważ pojawiły się wątpliwości pewnych wrednych ludzi zastąpiłem w pierwszym poście kod tym, który napisałem w całości sam.

7

Na githubie udostępniam swoją implementację dekodera, która używa biblioteki libucl1-dev. Kod znajdujący się w tym repozytorium w całości pochodzi z przykładów w/w biblioteki opracowanej w latach '90 i wydanej na licencji GPL.

https://github.com/icedevml/decode-polish-aztec

Wysyłanie nieprawidłowych DMCA względem tego repozytorium spowoduje podjęcie działań w kierunku ukarania za składanie fałszywych zeznań.

Załączam kod poniżej:

decompress_polish_aztec.c

/* decompress_polish_aztec.c -- decompress data from polish vehicle AZTEC code

   this file is an explicit modification of the following file from libucl1-dev:

   simple.c -- the annotated simple example program for the UCL library

   This file is part of the UCL data compression library.

   Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
   All Rights Reserved.

   The UCL library 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 2 of
   the License, or (at your option) any later version.

   The UCL library 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.

   You should have received a copy of the GNU General Public License
   along with the UCL library; see the file COPYING.
   If not, write to the Free Software Foundation, Inc.,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   Markus F.X.J. Oberhumer
   <[email protected]>
   http://www.oberhumer.com/opensource/ucl/
 */

#include <ucl/ucl.h>
#if defined(UCL_USE_ASM)
#  include <ucl/ucl_asm.h>
#endif

/* portability layer */
#define WANT_UCL_MALLOC 1
#include "portab.h"

#include <unistd.h>

int __acc_cdecl_main main(int argc, char *argv[])
{
    int r;
    ucl_bytep in;
    ucl_bytep out;
    ucl_uint in_len;
    ucl_uint out_len;
    ucl_uint new_len;
    int level = 5;                  /* compression level (1-10) */

    if (argc < 0 && argv == NULL)   /* avoid warning about unused args */
        return 0;

    fprintf(stderr, "\nUCL data compression library (v%s, %s).\n",
            ucl_version_string(), ucl_version_date());
    fprintf(stderr, "Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer\n");
    fprintf(stderr, "http://www.oberhumer.com/opensource/ucl/\n\n");


/*
 * Step 1: initialize the UCL library
 */
    if (ucl_init() != UCL_E_OK)
    {
        fprintf(stderr, "internal error - ucl_init() failed !!!\n");
        fprintf(stderr, "(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable `-DUCL_DEBUG' for diagnostics)\n");
        return 1;
    }


/*
 * Step 2: setup memory
 *
 * We want to compress the data block at `in' with length `in_len' to
 * the block at `out'. Because the input block may be incompressible,
 * we must provide a little more output space in case that compression
 * is not possible.
 */
    in_len = 256 * 1024L;
    out_len = 256 * 1024L;

    in = (ucl_bytep) ucl_malloc(in_len);
    out = (ucl_bytep) ucl_malloc(out_len);
    if (in == NULL || out == NULL)
    {
        fprintf(stderr, "out of memory\n");
        return 2;
    }

    ucl_uint rout_len = 0;
    rout_len = read(STDIN_FILENO, out, out_len);

/*
 * Step 5: decompress again, now going back from `out' to `in'
 */
    new_len = out_len;
    r = ucl_nrv2e_decompress_8(out+4,rout_len-4,in,&new_len,NULL);

    if (r == UCL_E_OK)
        for (int i = 0; i < new_len; i++) {
            printf("%c", in[i]);
        }
    else
    {
        /* this should NEVER happen */
        fprintf(stderr, "internal error - decompression failed: %d\n", r);
        return 5;
    }

    ucl_free(out);
    ucl_free(in);
    return 0;
}

/*
vi:ts=4:et
*/

portab.h

/* portab.h -- portability layer

   This file is part of the UCL data compression library.

   Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
   All Rights Reserved.

   The UCL library 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 2 of
   the License, or (at your option) any later version.

   The UCL library 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.

   You should have received a copy of the GNU General Public License
   along with the UCL library; see the file COPYING.
   If not, write to the Free Software Foundation, Inc.,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   Markus F.X.J. Oberhumer
   <[email protected]>
   http://www.oberhumer.com/opensource/ucl/
 */


#include <ucl/uclconf.h>

#if 0

#include "examples/portab_a.h"

#else

/* INFO:
 *   The "portab_a.h" version above uses the ACC library to add
 *   support for ancient systems (like 16-bit DOS) and to provide
 *   some gimmicks like win32 high-resolution timers.
 *   Still, on any halfway modern machine you can also use the
 *   following pure ANSI-C code instead.
 */

#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#undef NDEBUG
#include <assert.h>

#define __acc_cdecl_main
#define ACC_UNUSED(var)         ((void) &var)

#if defined(WANT_UCL_MALLOC)
#  define ucl_malloc(a)         (malloc(a))
#  define ucl_free(a)           (free(a))
#endif
#if defined(WANT_UCL_FREAD)
#  define ucl_fread(f,b,s)      (fread(b,1,s,f))
#  define ucl_fwrite(f,b,s)     (fwrite(b,1,s,f))
#endif
#if defined(WANT_UCL_UCLOCK)
#  define ucl_uclock_handle_t   int
#  define ucl_uclock_t          double
#  define ucl_uclock_open(a)    ((void)(a))
#  define ucl_uclock_close(a)   ((void)(a))
#  define ucl_uclock_read(a,b)  *(b) = (clock() / (double)(CLOCKS_PER_SEC))
#  define ucl_uclock_get_elapsed(a,b,c) (*(c) - *(b))
#endif
#if defined(WANT_UCL_WILDARGV)
#  define ucl_wildargv(a,b)     ((void)0)
#endif

#endif


/*
vi:ts=4:et
*/

Użycie:

$ sudo apt install libucl1-dev
$ g++ -o decompress decompress_polish_aztec.c -lucl
$ cat vehicle.bin
BgQAANtYAAJDAPkxAHwAQXIw7zcGNN4ANiox+w81HrUGOP8eUABSAEUA+1oAWQBEDv9OAFQAIABN3wAuClMAvlQPV/eKUhq9Wg5X7k58UtcWSVq9TF5J79pBZ+5PAEsG12bTSm5GVQBM/ntSAEH7L1dj+0MAS1vvMvovewo3Ut4wDi39HjEAN6Pbl0FNe3YgPt5Q3kv3IlSevVnX1z9FMmuCShL2WgBaG9umKADvSAApJnx75k+itwZMAEx9X0rvbkSOTXtOOF/DRy0WOW53fPYLFoMzLr0xAi3DGnevLQOCfJ/vQZ5TcBZrN0oa9k4AfA82Q4QaDzj3q8deN6sN7zIE/1x8lbMnQdwBQi5ZT86jL2tqNAr2MwAw34xSH+uPSVPYFxZThBMzON8AMJM5wQA3MwRcMX7bNcET2jInwyedE01HZ4dlM94qKy0DL38fNgAqeBszSxOvNIeKfHM7fCLxNQAwVkMtdzl7Xiw/YMyrFzxQACBWw+Hza7c3C93/NWuHg1OWRquPQ5KP02K9IBZT4QZC9oNZU7aXFiOX83U4ADJFC7ADhrNVCyOW8w9qMbEnZhdHbHxjdjIT7E4DW0M3OQuGaxYmCSSSSSr/
$ base64 -d vehicle.bin | ./decompress | iconv -f UCS-2LE -t UTF-8//TRANSLIT

UCL data compression library (v1.03, Jul 20 2004).
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
http://www.oberhumer.com/opensource/ucl/

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|
1
grzegorzzaw napisał(a):

Czy potrafi ktoś to przerobić na biblioteke C# pod WPF ?

Implementacja algorytmu NRV2E w języku C#:
https://bitbucket.org/bsoja/nrv2e-csharp

Oraz dekoder, który jej używa:
https://bitbucket.org/bsoja/polish-vehicle-registration-certificate-decoder/

Gotowe paczki są dostępne przez NuGeta: NRV2E oraz PolishVehicleRegistrationCertificateDecoder

0

Tutaj też była wersja oparta o otwartą bibliotekę niemająca nic wspólnego z kodem PELocka, ale ktoś ją wziął i zrobił DMCA: https://github.com/dex4er/drpdecompress
Nieładnie. Takie działanie jest niezgodne z prawem, przejawia też rażący brak szacunku dla własności intelektualnej.

1

Ten ktoś to cały czas ta sama osoba, ten sam troll pelock

1

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

1

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

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)

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

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.

4

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.

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

0

Czy ktoś może skodził wersję w PHP lub Javascipt do pliku HTML? :(

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