Сообщение от VICTOR
Посмотреть сообщение
Объявление
Свернуть
Пока нет объявлений.
Corona QR програмирование сертификата не проходящего проверку
Свернуть
X
-
Последний раз редактировалось HelloWorld_x0123; 28-11-2021, 12:48 AM.
-
Всем привет!
Пишу программу на Delphi для генерации QR-кода.
С библиотекой "Base64" проблем нет, строка отлично кодируется и расшифровуется. Сам QR генерируется динамически, по мере ввода в редактор и безупречно считывается любым сканером, прямо с экрана ноута :
Но вот с библиотекой "Base45" возникла проблема.
Я не могу перевести исходник на Delphi, так как не знаю синтаксис языка.
Кто-нибудь может помочь с переводом?
Комментарий
-
К сожалению, как у питона нет. Я смог перевести приблизительно, но увы, не могу правильно получить массив байт.
Исходящий поток пуст. что-то не правильно...
Вот часть кода Pascal (Delphi) :
PHP код:unit Base45;
interface
uses Classes;
procedure Base45_Decode(const AInput, AOutput: TStream);
implementation
const
DecodeTable: array[0..255] of byte = (
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36, 255, 255, 255, 37, 38, 255, 255, 255, 255, 39, 40, 255, 41, 42, 43,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, 255, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, (* UpperCase *)
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 255, 255, 255, 255,
255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, (* LowerCase *)
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255);
procedure Base45_Decode(const AInput, AOutput: TStream);
var
ch, a, b: byte;
x: word;
begin
ch:= 0;
repeat // Запускаем цикл
// Чтение входящего потока
AInput.Read(ch, 1);
a:= DecodeTable[ch];
// Дублируем чтение
AInput.Read(ch, 1);
b:= DecodeTable[ch];
// Если закончили, выходим из процедуры
if (a = 255) or (b = 255) then exit;
// Алгоритм кодирования
x:= a + 45 * b;
// Если текущая позиция (указатель) не достиг конца
if AInput.Position < AInput.Size then
begin
AInput.Read(ch, 1);
a:= DecodeTable[ch];
//
if a = 255 then exit;
x:= x + (a * 45 * 45);
// Сдвиг вправо на 8 байт
ch:= x shr 8;
// Записываем в исходящий поток
AOutput.Write(ch, 1);
end;
ch:= x and $FF;
AOutput.Write(ch, 1);
until AInput.Position = AInput.Size;
// Достигли конца - выход из цикла
end;
end.
Комментарий
-
Обратите внимание, приложение "Green Pass Wallet" не проверяет ключ на подлинность
и с этим QR можно идти в пивбар :
А вот приложение "SafeBorder" (используется ментами), проверку не проходит,
хотя отображает Фамилию - Имя, а также количество доз принятой вакцины :
Более того, если я в программе сгенерирую QR с пустым текстом HC1, без дополнительных данных
то приложение распознаёт код как сертификат, но с пустыми полями для Имени и Даты рождения :
Однако, если я заключу текст HC1 в кавычки или введу (абсолютно левый текст),
тогда приложение отображает его как "Контекст" и он уже не распознаётся как сертификат
и не имеет обрамляющей зелёной рамки вокруг :
Комментарий
-
Вопрос по-поводу библиотеки "Base45" остаётся открыты...
Вот исходник PHP :
PHP код:/* Base45 endocing/decoding Specification: https://datatracker.ietf.org/doc/draft-faltstrom-base45/ 30.3.2021 Chris Baumann - c.baumann@baumann.at */ $charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; function divmod($x, $y) { $resX = floor($x / $y); $resY = $x % $y; return(array($resX, $resY)); } function str2buffer($s) { $res = array(); for ($i=0; $i<strlen($s); $i++) { $res[] = ord($s[$i]); } return($res); } function b45str2buffer($s) { global $charset; $res = array(); for ($i=0; $i<strlen($s); $i++) { $p = strpos($charset, $s[$i]); if ($p === false) { throw new Exception('Invalid base45 value'); } else { $res[] = $p; } } return($res); } function base45_encode($input) { global $charset; $buffer = str2buffer($input); $res = ''; for ($i=0; $i<count($buffer); $i+=2) { if (count($buffer) - $i > 1) { $x = ($buffer[$i] << 8) + $buffer[$i+1]; list($e, $rest) = divmod($x, 45 * 45); list($d, $c) = divmod($rest, 45); $res .= @$charset[$c] . @$charset[$d] . @$charset[$e]; } else { list($d, $c) = divmod($buffer[$i], 45); $res .= @$charset[$c] . @$charset[$d]; } } return($res); } function base45_decode($input) { $buffer = b45str2buffer($input); $res = ''; for ($i=0; $i<count($buffer); $i+=3) { if (count($buffer) - $i >= 3) { $x = $buffer[$i] + $buffer[$i+1] * 45 + $buffer[$i+2] * 45 * 45; list($a, $b) = divmod($x, 256); $res .= chr($a) . chr($b); } else { $x = $buffer[$i] + $buffer[$i+1] * 45; $res .= chr($x); } } return($res); }
Как "это" перевести на Delphi ?
Миссия невыполнима ?
Комментарий
-
А вот на языке С :
Как чёрт возьми это перевести?...#include <ctype.h> // for size_t #include <string.h> // for strlen() /* Table 1: The Base 45 Alphabet Value Encoding Value Encoding Value Encoding Value Encoding 00 0 12 C 24 O 36 Space 01 1 13 D 25 P 37 $ 02 2 14 E 26 Q 38 % 03 3 15 F 27 R 39 * 04 4 16 G 28 S 40 + 05 5 17 H 29 T 41 - 06 6 18 I 30 U 42 . 07 7 19 J 31 V 43 / 08 8 20 K 32 W 44 : 09 9 21 L 33 X 10 A 22 M 34 Y 11 B 23 N 35 Z */ static const char BASE45_CHARSET[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; static char _C2I[256] = { 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 36, 255,255,255, 37, 38,255,255, 255,255, 39, 40, 255, 41, 42, 43, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44,255, 255,255,255,255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* uppercase */ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 255,255,255,255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* lowercase */ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, }; int base45_encode(char * dst, size_t *_max_dst_len, const unsigned char * src, size_t src_len) { size_t out_len = 0, max_dst_len; max_dst_len = _max_dst_len ? *_max_dst_len : src_len * 4; for(int i = 0; i < src_len; i+=2) { if (src_len - i > 1) { int x = ((src[i])<<8) + src[i+1]; unsigned char e = x / (45 * 45); x %= 45 * 45; unsigned char d = x / 45; unsigned char c = x % 45; if (out_len < max_dst_len && dst) dst[ out_len ] = BASE45_CHARSET[c]; out_len++; if (out_len < max_dst_len && dst) dst[ out_len ] = BASE45_CHARSET[d]; out_len++; if (out_len < max_dst_len && dst) dst[ out_len ] = BASE45_CHARSET[e]; out_len++; } else { int x = src[i]; unsigned char d = x / 45; unsigned char c = x % 45; if (out_len < max_dst_len && dst) dst[ out_len ] = BASE45_CHARSET[c]; out_len++; if (out_len < max_dst_len && dst) dst[ out_len ] = BASE45_CHARSET[d]; out_len++; } } /* Same non guarantee as strncpy et.al. */ if (out_len < max_dst_len && dst) dst[ out_len ] = 0; if (_max_dst_len) *_max_dst_len = out_len; return 0; } int base45_decode(unsigned char * dst, size_t * _max_dst_len, const char * src, size_t src_len) { size_t out_len = 0, max_dst_len; max_dst_len = _max_dst_len ? *_max_dst_len : src_len; if (dst == NULL && _max_dst_len == NULL) return -2; if (src == NULL) return -2; if (src_len == 0) src_len = strlen(src); for(int i = 0; i < src_len; i+=3) { int x,a,b; if (src_len - i < 2) return -1; if ((255 == (a = _C2I[src[i]])) || (255 == (b = _C2I[src[i+1]]))) return -1; x = a + 45 * b; if (src_len - i >= 3) { if (255 == (a = _C2I[src[i+2]])) return -1; x += a * 45 * 45; if (out_len < max_dst_len && dst) dst[out_len] = x / 256; out_len++; x %= 256; }; if (out_len < max_dst_len && dst) dst[out_len] = x; out_len++; }; if (_max_dst_len) *_max_dst_len = out_len; return 0; } #ifdef BASE45_UTIL #include <stdio.h> #include <stdlib.h> int main(int argc, char ** argv) { FILE * in = stdin; FILE * out = stdout; int decode = 0; int at = 1; if (argc > 1 && argv[at][0] == '-') { if (argv[at][1] == 'd') decode = 1; else { fprintf(stderr,"Syntax: %s [-d] [infile [outfile]]\n", argv[0]); exit(1); }; at++; argc--; }; if (argc > 1) { if (NULL == (in = fopen(argv[at],"r"))) { perror("Cannot open input file for reading:"); exit(1); }; at++; argc--; }; if (argc > 1) { if (NULL == (out = fopen(argv[at],"w"))) { perror("Cannot open out file for writing:"); exit(1); }; at++; argc--; }; #ifdef VALIDATE for(int i = 0; i < 45; i++) assert(i == _C2I[BASE45_CHARSET[i]]); #endif while(!feof(in)) { unsigned char buff[ 3 * 1024 ]; // multiple chosen to allow continuation. unsigned char outbuf[ 3 * 3 * 1024 ]; size_t olen = sizeof(outbuf); size_t len = fread(buff, 1, 3 * 1024, in); buff[len] = 0; if (len) { int e; if (decode) e = base45_decode(outbuf, &olen, (char *) buff, len); else e = base45_encode((char *)outbuf, &olen, buff, len); if (e) { fprintf(stderr,"base45 %s failed\n", decode ? "decode" : "encode"); exit(1); }; if (olen) fwrite(outbuf, 1, olen, out); }; } fclose(out); return(0); }; #endif
Комментарий
-
Попробую поспрашивать на форуме "4pda".
По-сути, в библиотеки всего 2 функции для ко/декодирования строки.
JSON в топку, я нашёл альтернативу в виде широкой строки WideString и не нужно создавать каждый раз объект для пары "Имя" : "значение".
Это вообще полная дурость.
Зачем генерировать QR?
У меня есть безумная идея, хочу проверить, но только
после интегрирования библиотеки в свой проект.
Комментарий
-
ну скажи может и не стоит безумием страдать
повторюсь: ты можешь сделать ексешник, который будет скомпилирован из пхп или питона, давать на него с делфи стринг и получать ответ.
https://stackoverflow.com/questions/...ows-executable
если ты конечно в делфи имеешь возможность запустить внешнее приложение.
Комментарий
-
Ну конечно можно вызывать из Delphi чужие приложения.
От языка С его отличает только синтаксис.
Неважно на каком языке я скажу фразу "Я тебя люблю" -
на французком или на русском, смысл слов от этого не изменится. Делфи в этом плане даже легче в освоении.
Можно также попробовать запихнуть исходник С в динамическую библиотеку ".dll" и вызывать её функции из
".exe". Конечно, хотелось бы, чтобы прога была полностью написана на одном языке. Попробую изучить код исходника, логика мне понятна и работа некоторых операторов, но ошибка всего лишь на один символ, может привести к неверному результату или полной неработоспособности программы.
Ох, говорила мне мама в школе: "Учись сынок, учись!"...
У меня есть свой, более важный проект на Delphi, а я отвлекаюсь на какую-то фигню с QR кодами.
Комментарий
-
ну удачи тебе в гуглении
https://stackoverflow.com/questions/...-php-to-delphi
кроме разницы в операторах вроди ничего другово нет
https://www.delphipraxis.net/208757-covid-zertifikatscheck.html#post1494623
немец грозился написать, да походу одумался, нах оно нужно
Комментарий
-
Я нашёл статью на зарубежном форуме, датируемую декабрём 2017 года, тоесть 5 лет назад :
https://tech-codeyellow-nl.translate...&_x_tr_pto=nui
Там обсуждают на тот момент разработку новой библиотеки "Base45".
Лишний раз убеждаюсь в том, что всё это готовилось заранее, а не появилось спонтанно в начале лета.
5 лет Карл !!!
Они планировали разработку этих сертификатов ещё тогда.
Комментарий
-
Это верно, но как правило никто из производителей информацию перед записью в QR не кодирует, а записывает "как есть". А тут придумали совсем новый алгоритм кодирования. Кроме того, я до этого лета, нигде на форумах программистов не встречал даже упоминания о библиотеке "Base45".
Где ещё эта библиотека применяется?, в какой отрасли?,
для чего?. Да нигде!
Комментарий
Комментарий