Виведіть 2015 як QR-код


15

Місія проста. Просто виведіть номер 2015 як QR-код і запишіть його у файл з назвоюnewyear.png у форматі PNG. Код повинен бути дійсним в будь-який день, тому, можливо, ви не будете використовувати поточний рік.

QR-код у вигляді тексту виглядає так:

# # # # # # #   # # # #     # # # # # # #
#           #           #   #           #
#   # # #   #   # #     #   #   # # #   #
#   # # #   #       #   #   #   # # #   #
#   # # #   #       #   #   #   # # #   #
#           #               #           #
# # # # # # #   #   #   #   # # # # # # #
                #   # #
#   #     # #     # #     # #       #   #
  # # #   #   #   #   # #   #     #   # #
#   # #   # # #   # # # # # #   #       #
# # #         # #         # # # #
# # # # #   #   #     #     #   #     #
                      # # # #
# # # # # # #       #   # #   # #   #   #
#           #   #         # # # #
#   # # #   #         #     #   #     #
#   # # #   #     #     # # # # #
#   # # #   #   #   #   # #   # #   #   #
#           #     # #       # # #   # # #
# # # # # # #   #           #   #   #   #

Введений результат newyear.pngповинен містити QR-код із білими 5-піксельними рамками та однією точкою розміру пікселя. Він не повинен містити нічого іншого, крім QR-коду.


1
це може бути жорстко закодовано, або ви повинні створити код qr?
— підземниймонорельс

7
Набагато більше відповідей надійде, якщо це заснований на результатах мистецтва ascii, а не вихід зображення.
— Оптимізатор

6
Чи має бути код точно правильним, без помилок, чи достатньо, щоб він сканувався правильно? (QR-коди мають багато навмисних надмірностей та виправлення помилок, тому ви можете перегортати багато пікселів, і вони все одно працюватимуть.) Також, чи повинен це бути PNG чи ми можемо використовувати інші формати зображень (я думаю особливо про PBM тут)?
— Ільмарі Каронен

Відповіді:


12

Сирий файл, 184 байти = 173-байтний файл + 11-байтне ім’я файлу

Сподіваюсь, це не порушує жодних стандартних лазів. Але вихід "має високу і найкоротшим способом його виготовлення було б (швидше за все) просто надрукувати його буквально ...".

newyear.png

База 64 файлу:

iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQAAAAA31SuUAAAAdElEQVR4XnXOMQ5BQRRA0euVRFgGCq1ubIyJpSh11I
qJWIjo+fnt/JnJe55WornlycXMVAB+Qp49A7U/J8rqlIQReG5Quz6Rx8eA6VaF5R7a5arooXg2LaKvd8KGRyBPJLoy
D640pxZ3pay/creL5KnEvwcfvE46ggJMibIAAAAASUVORK5CYII=

Замість програми для гольфу я пограв в результаті зображення PNG. QR-код - це дуже гнучкий формат, є безліч параметрів, які можна змінити: кодування вводу, рівень виправлення помилок та маскувальне зображення. Усі вони генерують різні символи і, таким чином, стискаються до файлів різного розміру.

Отже, я написав програму для генерації всіх цих комбінацій (в результаті 6720 файлів), а потім використовую PNGOUT, щоб вибрати ту, яка стискається до найменшого файлу. Виявляється файл, який:

  • Спочатку напишіть "20" в буквено-цифровому режимі
  • Потім напишіть "1" в цифровому режимі
  • Потім напишіть "5" в цифровому режимі
  • Використовуйте "H" (Високий) рівень виправлення помилок
  • Використовуйте маскування даних "110"

Це називається, test-3-1-H-Diamonds.bmpякщо ви використовували програму нижче. Це зображення має 175-байтовий термін після запуску PNGOUT. За допомогою "високого" рівня виправлення помилок у QR-коді "версія 1" ми можемо змінювати до 8 пікселів у частині даних, не руйнуючи дані. Маючи трохи ручних проб і помилок, я можу знизити його ще до 173 байтів, представлених вище. Можливо, це може бути менше, але для вичерпання всіх комбінацій потрібно 208 C 8 ~ 7,5 × 10 13 перевірок, які я не збираюся робити;)


Програма "Іржа" (0.13.0 за ніч (5ba610265)), яка генерує всі комбінації:

/* 

Also put these into your Cargo.toml: 

[dependencies]
qrcode = "0.0.3"
bmp = "0.0.3"

*/

extern crate qrcode;
extern crate bmp;

use qrcode::bits::Bits;
use qrcode::optimize::Segment;
use qrcode::types::{Version, EcLevel, Mode};
use qrcode::ec::construct_codewords;
use qrcode::canvas::{Canvas, MaskPattern, Module};

use bmp::{Image, Pixel};

use std::num::Int;

const BLACK: Pixel = Pixel { r: 0, g: 0, b: 0};
const WHITE: Pixel = Pixel { r: 255, g: 255, b: 255 };

static SEGMENT_SEPARATIONS: [&'static [(uint, uint)]; 8] = [
    &[(0, 1), (1, 2), (2, 3), (3, 4)],
    &[(0, 1), (1, 2), (2, 4)],
    &[(0, 1), (1, 3), (3, 4)],
    &[(0, 2), (2, 3), (3, 4)],
    &[(0, 1), (1, 4)],
    &[(0, 2), (2, 4)],
    &[(0, 3), (3, 4)],
    &[(0, 4)],
];

const ALL_EC_LEVELS: &'static [EcLevel] = &[EcLevel::L, EcLevel::M, EcLevel::Q, EcLevel::H];
const ALL_MODES: &'static [Mode] = &[Mode::Numeric, Mode::Alphanumeric, Mode::Byte];
const ALL_MASK_PATTERNS: &'static [MaskPattern] = &[
    MaskPattern::Checkerboard,
    MaskPattern::HorizontalLines,
    MaskPattern::VerticalLines,
    MaskPattern::DiagonalLines,
    MaskPattern::LargeCheckerboard,
    MaskPattern::Fields,
    MaskPattern::Diamonds,
    MaskPattern::Meadow,
];

fn run(ec_level: EcLevel, mask_pattern: MaskPattern, segments: &[Segment], filename: &str) {
    let version = Version::Normal(1);
    let mut bits = Bits::new(version);
    if bits.push_segments(b"2015", segments.iter().map(|s| *s)).is_err() {
        return;
    }
    if bits.push_terminator(ec_level).is_err() {
        return;
    }
    let data = bits.into_bytes();
    let (encoded_data, ec_data) = construct_codewords(&*data, version, ec_level).unwrap();
    let mut canvas = Canvas::new(version, ec_level);
    canvas.draw_all_functional_patterns();
    canvas.draw_data(&*encoded_data, &*ec_data);
    canvas.apply_mask(mask_pattern);
    let canvas = canvas;

    let width = version.width();
    let real_image_size = (width + 10) as uint;
    let mut image = Image::new(real_image_size, real_image_size);
    for i in range(0, real_image_size) {
        for j in range(0, real_image_size) {
            image.set_pixel(i, j, WHITE);
        }
    }
    for i in range(0, width) {
        for j in range(0, width) {
            if canvas.get(i, j) == Module::Dark {
                image.set_pixel((i + 5) as uint, real_image_size - (j + 6) as uint, BLACK);
            }
        }
    }
    image.save(filename);
}

fn main() {
    for (z, separations) in SEGMENT_SEPARATIONS.iter().enumerate() {
        let mut segments = separations.iter().map(|&(b, e)| Segment {
            mode: Mode::Numeric, begin: b, end: e
        }).collect::<Vec<_>>();

        let variations_count = ALL_MODES.len().pow(segments.len());
        for i in range(0, variations_count) {
            let mut var = i;
            for r in segments.iter_mut() {
                r.mode = ALL_MODES[var % ALL_MODES.len()];
                var /= ALL_MODES.len();
            }
            for ec_level in ALL_EC_LEVELS.iter() {
                for mask_pattern in ALL_MASK_PATTERNS.iter() {
                    let filename = format!("results/test-{}-{}-{}-{}.bmp", z, i, *ec_level, *mask_pattern);
                    run(*ec_level, *mask_pattern, &*segments, &*filename);
                }
            }
        }
        println!("processed {}/{}", z, 8u);
    }
}

1
Основна проблема, яку я бачу тут, полягає в тому, що ваше подання написане не мовою програмування .
— Мартін Ендер

4
@ MartinBüttner Це суб'єктивна думка декількох людей. Це, як було сказано, те, як файл був запрограмований, тому я б сказав, що це цілком коректне подання. Також це страхітливий дивовижний підхід.
— Ніт

1
@Nit Це мета-пост без зворотних запитів, який в основному працює як консенсус громади щодо SE (принаймні, щодо PPCG). Якщо ви не погоджуєтесь, ви можете спростувати цю відповідь або надати альтернативу. Якщо говорити, я, мабуть, викладу окремий мета-пост, зокрема про проблеми складності колмогорів, оскільки цього дуже багато.
— Мартін Ендер

@Nit Done. Сміливо заходьте обговорити це на мета.
— Мартін Ендер

Перетворення з gif здавалося коротшим.
— jimmy23013

5

Математика, 217 177 176 166 байт

Ось початок:

"newyear.png"~Export~ImagePad[Image[IntegerDigits[36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okk‌​lg0cymmy2,2,441]~Partition~21],5,1]

Менше гольфу:

"newyear.png"~Export~ImagePad[
 Image[
  IntegerDigits[
    36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okk‌​lg0cymmy2,
    2,
    441
  ]~Partition~21
 ],
 5,
 1
]

QR-код закодований в базовому номері 36. Звичайно, я міг би кодувати його в розширеному ASCII (база 256), але це лише скоротить рядок на 30 байт, і я не впевнений, що зможу зробити перетворення вартістю набагато менше, ніж це.

Звичайно, це Mathematica, тому є і 63-байт

"newyear.png"~Export~ImagePad[BarcodeImage["2015","QR",21],5,1]

але я думаю, що це стандартна лазівка. ;) (Це створює інший QR-код, ніж той, який викликає виклик, тому я думаю, QR-код не унікальний?)


1
Так, існує кілька способів кодування однієї струни в QR-коді, наприклад, використання різних рівнів перевірки помилок, схема кодування, маскування зображення тощо. Незважаючи на те, що код стиснення OP є одним з найменших («версія 1»).
— kennytm

ВідDigits? Ви можете використати 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2натомість.
— kennytm

@KennyTM ого, охайний трюк. Дякую :) Я думаю, що з цим, база 256 справді не варта (мені знадобиться і те, ToCharacterCodeі FromDigitsпотім.)
— Мартін Ендер

3

Матлаб 545 байт

новий рік

Жорстко копається в кропітка ручна робота і без будь-яких фантазійних побудованихв стисканні струни / розмови . Я знаю, що це все ще не так добре, як інші відповіді, але я все ще задоволений =)

b=[[61:67,69,71:73,75:81,92,98]+100,
    1,3:4,6,12,23,25:27,29,31:35,37,39:41,43,54,56:58,60,63:64,66,68,70:72,74,85,87:89,91,97,99]+200,
    [1:3,5,16,22,24:26,30,36,47:53,55,57,59,61:67,87:89]+300,
    [9,11,15:16,20:21,24,27,29,40,42,48:50,57,59,71,74:75,77:79,81,85,89:90]+400,
    [2,9,11:12,14:15,18,34:37,39,42:43,46:47,50:51,72,74:75,77:79,81:82,95:99]+500,
    [0:1,3:8,10:12,14:15,26,32,37,40:41,43:45,57,59:61,63,67:69,71:77,88,90:92,94,97]+600,
    [19,21:23,25,27,33,37:39,50,56,59,62,66,69,81:87,89:91,95,99:101]+700];
z=zeros(31);z(b)= 1;imwrite(~z,'newyear.png')

Більш нечитабельна (фактична версія 545):

z=zeros(31);
z([
    [61:67, 69, 71:73, 75:81, 92, 98] + 100,
    [1, 3:4, 6, 12, 23, 25:27, 29, 31:35, 37, 39:41, 43, 54, 56:58, 60, 63:64, 66, 68, 70:72, 74, 85, 87:89, 91, 97, 99] + 200,
    [1:3, 5, 16, 22, 24:26, 30, 36, 47:53, 55, 57, 59, 61:67, 87:89] + 300,
    [9, 11, 15:16, 20:21, 24, 27, 29, 40, 42, 48:50, 57, 59, 71, 74:75, 77:79, 81, 85, 89:90] + 400,
    [2, 9, 11:12, 14:15, 18, 34:37, 39, 42:43, 46:47, 50:51, 72, 74:75, 77:79, 81:82, 95:99] + 500,
    [0:1, 3:8, 10:12, 14:15, 26, 32, 37, 40:41, 43:45, 57, 59:61, 63, 67:69, 71:77, 88, 90:92, 94, 97] + 600,
    [19, 21:23, 25,27, 33, 37:39, 50, 56, 59, 62, 66, 69, 81:87, 89:91, 95, 99:101] + 700
])= 1;
imwrite(~z,'newyear.png')

Ми створюємо нульову матрицю 31 x 31, але отримуємо доступ до неї як вектор, щоб встановити всі комірки з індексами bдо 1. Використовувані мною трюки були позначення послідовних цілих чисел (наприклад[1,2,3,4] = 1:4 ) та вилучення одного 100-значного, додаючи скаляр до кожного значення вектора.

Подивимось, чи може хтось перемогти це =)


так що я не читав слово unreadableправильно ... обов'язково читав readable. побачив це відразу після того, як запропонував це, і сподівався, що хто прочитає мою редакцію, відкинув її, але вони занадто очевидно пропустили її. вибачте за погану редагування ...
— pseudonym117

Не має значення IMHO, просто хотіли включити першу версію, оскільки її легше посилатись у поясненні.
— недолік

2

Баш, 206 252 257 байт

Використання convertкоманди в imagemagickпакеті зберігає ще 46 байт.

base64 -d<<<UDQKMzAgMzAKAAAAAAAAAAAAAAAAAAAAAAAAAAAH9L+ABBkggAXULoAF2S6ABdOugAQeoIAH+r+AB9zVAABIlwABHU6AAsIaAAFXS4AAD+QAB/ywAAQT5QAF3pIABd6SAAXdTgAEHBsAB/1OAAAAAAAAAAAAAAAAAAAAAAAAAAAA|convert - newyear.png

Перетворює закодоване pbmзображення base64 у pngзображення з imagemagick's convert.

Вам може знадобитися налаштувати decode (-d)параметр під ваш конкретний base64бінарний файл. Тестовано на моєму Ubuntu 14.04 LTS.

Збережено 5 байт за допомогою <<</ here-string .

base64 -d>newyear.png<<<iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=

Стара версія (257 байт):
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

Просто простий ланцюг команд оболонки, який записує закодований pngфайл base64 у stdin, base64який розшифровує його через -dпрапор і записує його stdout в newyear.png.


Можливо, я можу зберегти персонажів із чимось на зразок, base64 -d>newyear.png<<<[the long string]але я не на машині Linux rn, і я не знаю, який пробіл є обов'язковим
— undergroundmonorail

Підтверджено для роботи з base64 -d>newyear.png<<<[base64 string]Ubuntu 14.04.
— PurkkaKoodari

Якщо ви збираєтесь використовувати запропонований код, просто відредагуйте заголовок відповіді на щось конкретне, наприклад, Bash, Ksh або Zsh. Shell в цілому (як сумісний з POSIX Sh, Ash або Dash) не підтримує синтаксис тут-рядка .
— манастирство

Якщо ми можемо використовувати Netpbm процедури, ми можемо годувати стисненого растрових зображень і втрачають 40 байт: відлуння UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA == | base64 -d | pnmtopng> newyear.png
— swstephe

@manatwork Щойно відредагований, повинен працювати на Bash, як я тестував його на своєму телефоні Android.
— GiantTree

1

Python 2 + PIL, 216 215

В основному порт рішення Mathematica.

from PIL import*
b=Image.new("1",[21]*2)
b.putdata(map(int,'0'*7+bin(int('FL6IBG25C8Z00UEF53P4657DGD6HJZG41E5JOEAD1QGZ0L2XCHQGSO5R1A51V5NO4ZKW9V22OKKLG0CYMMY2',36))[2:]))
ImageOps.expand(b,5,255).save("newyear.png")

0

Загальні інструменти Shell + Imagemagick, 215

(echo "P1
21 21"
base64 -d<<<H95/ggoN1lduirt0VdggIP9V/ALAFMzFdVpdu/R4YeH1JSAB4H8W1goeF0JSuk+F1W1gmO/9BVA=|xxd -c99 -p|tr a-f A-F|dc -e2o16i?p|tr -d '\n\\'|fold -21)|convert -border 5 -bordercolor white - newyear.png

Трохи перекручений , але коротший за інші відповіді на оболонку .

  • Base64 перетворює з base64 на базу 256 (розширений ASCII)
  • xxd перетворюється в hex
  • tr робить шістнадцятковий верхній регістр, підходить для постійного струму
  • DC читає шістнадцятковий і друкує двійковий рядок 1s і 0s
  • tr видаляє \ та пробіли
  • fold робить лінії в 21 символів (21 пікселя)
  • Цей вихід, поряд з P1\n21 21це формат PBM Р1
  • convert (Imagemagick) перетворює це в .png з межею в 5 пікселів:

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.