Виведіть 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.