Попробую расписать подробнее, то о чем я упоминал ранее.
"Шифрование" не совсем удачный термин (и способ) в данном случае. Тут больше подойдет "цифровая подпись"/"хэш" для номера карты.
По уровню надежности примерно то же самое что и шифрование, по сложности реализации - проще.
В QR/Штрих коде рисуем:
XXXX-Y
где XXXX - истинный номер карты (в открытом виде)
Y - цифровая подпись от номера (в простейшем случае контрольная сумма)
"-" разделитель
Разделитель можно не использовать и тогда работать "по маске" XXXXY (последний символ это Y остальное это XXXX)
Y считается от Х по какому то "секретному" правилу. Как простой пример:
Y = MOD["сумма всех четных цифр в Х" - "сумма всех не четных цифр в Х"]
Для номера 5781 это будет
MOD[(7+1)-(5+8)]=MOD[8-13]=MOD[-5]=5 <- Это значение Y (для случая если Y получился больше 9 надо откинуть первую цифру)
ШК будет выглядеть так: "5781-5"
Читаем карту, отделяем номер от подписи, считаем сами подпись, сверяем с той подписью что считали с карты. Если ок - работаем, если нет - ошибка.
Этот вариант легко реализовать в MCR, но он очень простой (зная несколько реальных ШК можно вычислить "секретный" алгоритм). А еще проще брутфорсом перебрать последнюю цифру от 0 до 9 для любого номера карты.
Более сложный вариант это писать в ШК что то типа XXXX-YYYY, где ХХХХ это так же номер карты в открытом виде, а YYYY это значение некой ХЭШ функции от ХХХХ.
MD5 на кипере конечно не сделать (нет такой встроенной функции в языке, а писать ее в ручную тяжко на скриптовом языке).
Но есть множество более простых алгоритмов, которые можно реализовать в MCR.
Гуглить запрос "простые хэш функции".
При этом, т.к. хэш функция будет все таки достаточно простой, желательно использовать "соль" при хэшировании.