Saída 2015 como código QR

15

A missão é simples. Basta imprimir o número 2015 como código QR e gravá-lo no arquivo nomeado newyear.pngno formato PNG. O código deve ser válido a qualquer dia, portanto, talvez você não deva usar o ano atual.

O código QR como texto fica assim:

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

O resultado escrito newyear.pngdeve conter esse código QR com bordas brancas de 5 pixels e pontos com tamanho de um pixel. Não deve conter nada além de código QR.

Hannes Karppila
fonte
1
pode ser codificado ou você deve gerar o código qr?
undergroundmonorail
7
Muito mais respostas virão se for baseado na produção artística e não na imagem.
Optimizer
6
O código precisa estar exatamente correto, sem erros, ou é suficiente para que ele seja verificado corretamente? (Os códigos QR têm muita redundância deliberada e correção de erros, para que você possa inverter muitos pixels e eles ainda funcionem.) Além disso, ele precisa ser PNG ou podemos usar outros formatos de imagem (estou pensando particularmente sobre PBM aqui)?
Ilmari Karonen

Respostas:

12

Arquivo bruto, 184 bytes = arquivo de 173 bytes + nome de arquivo de 11 bytes

Espero que isso não rompa nenhuma brecha padrão. Mas o resultado "tem uma alta e a maneira mais curta de produzi-lo (provavelmente) seria imprimi-lo literalmente ...".

newyear.png

Base 64 do arquivo:

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

Em vez de jogar golfe em um programa, joguei a imagem PNG resultante. O código QR é um formato muito flexível, existem muitos parâmetros que podem ser alterados: a codificação da entrada, o nível de correção de erros e a imagem de máscara. Todos eles irão gerar símbolos diferentes e, assim, compactados em arquivos de tamanhos diferentes.

Então, eu escrevi um programa para gerar todas essas combinações (arquivos 6720 resultantes) e, em seguida, use o PNGOUT para escolher o que compactou no menor arquivo. Acontece que é um arquivo que:

  • Primeiro escreva "20" no modo alfanumérico
  • Em seguida, escreva "1" no modo numérico
  • Em seguida, escreva "5" no modo numérico
  • Use o nível de correção de erros "H" (Alto)
  • Use o mascaramento de dados "110"

Isso é chamado test-3-1-H-Diamonds.bmpse você usou o programa abaixo. Esta imagem tem 175 bytes de comprimento após a execução do PNGOUT. Com o nível "alto" de correção de erros no código QR "versão 1", podemos modificar até 8 pixels na parte dos dados sem danificá-los. Com um pouco de tentativa e erro manual, posso reduzi-lo ainda mais para 173 bytes apresentados acima. Provavelmente pode ser menor, mas esgotar todas as combinações requer 208 C 8 ~ 7,5 × 10 13 verificações que eu não vou fazer;)


O programa Rust (0.13.0-nightly (5ba610265)) que gera todas as combinações:

/* 

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);
    }
}
kennytm
fonte
1
O principal problema que vejo aqui é que o envio não está escrito em uma linguagem de programação .
Martin Ender
4
@ MartinBüttner Essa é uma opinião subjetiva de algumas poucas pessoas selecionadas. Dito isto, a maneira como o arquivo foi obtido foi programado, então eu diria que este é um envio completamente válido. Além disso, esta é uma abordagem incrível.
Nit
1
@Nit É um meta post sem votos negativos, que é basicamente como o consenso da comunidade funciona no SE (pelo menos no PPCG). Se você não concordar, você pode votar negativamente essa resposta ou fornecer uma alternativa. Dito isto, provavelmente farei um meta post separado, especificamente sobre os desafios da complexidade kolmogorov, pois isso está surgindo bastante.
Martin Ender
@Nit Done. Sinta-se à vontade para vir discutir isso na meta.
Martin Ender
A conversão de gif parecia mais curta.
jimmy23013
5

Mathematica, 217 177 176 166 bytes

Aqui está um começo:

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

Menos golfe:

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

O código QR é codificado em um número base 36. É claro que eu poderia codificá-lo em ASCII estendido (base 256), mas isso só reduziria a string em 30 bytes, e não tenho certeza de que posso fazer a conversão ao custo de muito menos do que isso.

Claro, este é o Mathematica, então há também os 63 bytes

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

mas acho que é uma brecha padrão. ;) (Isso produz um código QR diferente do código do desafio, então acho que o código QR não é único?)

Martin Ender
fonte
1
Sim, existem várias maneiras de codificar a mesma sequência no código QR, por exemplo, usando diferentes níveis de verificação de erro, esquema de codificação, imagem de mascaramento, etc.
Kennytm
FromDigits? Você poderia usar em seu 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2lugar.
Kennytm
@KennyTM oh uau, truque puro. Obrigado :) Eu acho que com isso, base 256 é realmente não vale a pena (eu precisaria de ambos ToCharacterCodee FromDigits, em seguida,.)
Martin Ender
3

Matlab 545 Bytes

ano Novo

Codificado no trabalho manual meticuloso e sem nenhuma compactação / conversa sofisticada de cordas incorporadas . Eu sei que ainda não é tão bom quanto as outras respostas, mas ainda estou feliz =)

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')

Mais ilegível (a versão real 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')

Criamos uma matriz zero 31 x 31, mas a acessamos como vetor para definir todas as células com os índices de bpara 1. Os truques que usei foram a notação de números inteiros consecutivos (como[1,2,3,4] = 1:4 ) e a remoção de um com 100 dígitos, adicionando um escalar a todos os valores do vetor.

Vamos ver se alguém consegue superar isso =)

flawr
fonte
então eu não li a palavra unreadablecorretamente ... definitivamente li readable. vi isso logo após sugeri-lo e esperava que quem lesse a minha edição o rejeitasse, mas eles aparentemente não entenderam. desculpe a má editar ...
pseudonym117
Não importa o IMHO, apenas queria incluir a primeira versão, porque é mais fácil fazer referência na explicação.
flawr
2

Bash, 206252257 bytes

O uso do convertcomando incluído imagemagickeconomiza mais 46 bytes.

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

Converte a pbmimagem codificada em base64 em uma pngimagem com imagemagick's convert.

Pode ser necessário ajustar o decode (-d)parâmetro ao seu base64binário específico . Testado no meu Ubuntu 14.04 LTS.

Salva 5 bytes usando <<</ here-string .

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

Versão antiga (257 bytes):
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

Apenas uma cadeia de comandos shell simples que grava o pngarquivo codificado em base64 no stdin e base64o decodifica por causa do -dsinalizador e grava seu stdout em newyear.png.

GiantTree
fonte
provavelmente pode salvar personagens com algo parecido base64 -d>newyear.png<<<[the long string], mas eu não estou em um rn máquina linux e eu não sei qual o espaço em branco é obrigatória
undergroundmonorail
Confirmado para trabalhar com o base64 -d>newyear.png<<<[base64 string]Ubuntu 14.04.
PurkkaKoodari
Se você for usar o código sugerido, basta editar o cabeçalho da resposta para algo específico como Bash, Ksh ou Zsh. O shell em geral (como Sh, Ash ou Dash compatível com POSIX) não suporta a sintaxe aqui .
manatwork
Se podemos usar rotinas netpbm, podemos alimentar o bitmap comprimido e perder 40 bytes: echo UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA == | base64 -d | pnmtopng> newyear.png
swstephe
@manatwork Apenas editado, deve funcionar no Bash enquanto eu o testei no meu telefone Android.
GiantTree
1

Python 2 + PIL, 216 215

Basicamente, uma porta da solução 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")
PurkkaKoodari
fonte
0

Ferramentas comuns do 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

Um pouco complicado , mas mais curto que a outra resposta do shell .

  • Base64 converte de base64 para base 256 (ASCII estendido)
  • xxd converte em hexadecimal
  • tr faz hexa maiúsculo, adequado para CC
  • dc lê hexadecimal e imprime uma sequência binária de 1s e 0s
  • tr remove \ e espaço em branco
  • fold faz linhas com 21 caracteres (21 pixels)
  • Esta saída, juntamente com P1\n21 21o formato PBM P1
  • convert (Imagemagick) converte isso em .png com uma borda de 5 pixels:

insira a descrição da imagem aqui

Trauma Digital
fonte