Sortie 2015 comme code QR


15

La mission est simple. Il suffit de sortir le numéro 2015 sous forme de code QR et de l'écrire dans un fichier nommé newyear.pngau format PNG. Le code doit être valide n'importe quel jour, donc vous ne devrez peut-être pas utiliser l'année en cours.

Le code QR sous forme de texte ressemble à ceci:

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

Le résultat écrit newyear.pngdoit contenir ce code QR avec des bordures blanches de 5 pixels et des points d'un pixel. Il ne doit contenir rien d'autre que du code QR.


1
peut-il être codé en dur, ou devez-vous générer le code qr?
undergroundmonorail

7
Beaucoup plus de réponses viendront s'il s'agit d'une sortie ascii art et non d'une sortie image.
Optimizer

6
Le code doit-il être exactement correct sans erreur, ou suffit-il qu'il scanne correctement? (Les codes QR ont beaucoup de redondance délibérée et de correction d'erreur, vous pouvez donc retourner beaucoup de pixels et ils fonctionneront toujours.) De plus, faut-il que ce soit PNG, ou pouvons-nous utiliser d'autres formats d'image (je pense en particulier sur PBM ici)?
Ilmari Karonen

Réponses:


12

Fichier brut, 184 octets = fichier de 173 octets + nom de fichier de 11 octets

J'espère que cela ne rompt aucune faille standard. Mais la sortie "a une élevée et la façon la plus courte de la produire serait (très probablement) de l'imprimer littéralement ...".

newyear.png

Base 64 du fichier:

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

Au lieu de jouer à un programme, j'ai joué à l'image PNG résultante. Le code QR est un format très flexible, de nombreux paramètres peuvent être manipulés: l'encodage de l'entrée, le niveau de correction d'erreur et l'image de masquage. Ceux-ci généreront tous des symboles différents et donc compressés en fichiers de tailles différentes.

J'ai donc écrit un programme pour générer toutes ces combinaisons (6720 fichiers résultants), puis utiliser PNGOUT pour choisir celui qui a compressé dans le plus petit fichier. Il s'agit d'un fichier qui:

  • Écrivez d'abord "20" en mode alphanumérique
  • Puis écrivez "1" en mode numérique
  • Puis écrivez "5" en mode numérique
  • Utiliser le niveau de correction d'erreur "H" (élevé)
  • Utilisez le masquage de données "110"

Ceci est appelé test-3-1-H-Diamonds.bmpsi vous avez utilisé le programme ci-dessous. Cette image fait 175 octets longtemps après l'exécution de PNGOUT. Avec un niveau de correction d'erreur «élevé» dans le code QR «version 1», nous pouvons modifier jusqu'à 8 pixels dans la partie des données sans ruiner les données. Avec un peu d'essais et d'erreurs manuels, je peux le réduire à 173 octets présentés ci-dessus. Il peut probablement être plus petit mais épuiser toutes les combinaisons nécessite 208 C 8 ~ 7,5 × 10 13 vérifications que je ne vais pas faire;)


Le programme Rust (0.13.0-nightly (5ba610265)) qui génère toutes les combinaisons:

/* 

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
Le principal problème que je vois ici, c'est que votre soumission elle-même n'est pas écrite dans un langage de programmation .
Martin Ender

4
@ MartinBüttner C'est une opinion subjective de quelques personnes sélectionnées. Cela étant dit, la façon dont le fichier a été obtenu a été programmée, donc je dirais que c'est une soumission tout à fait valide. De plus, c'est une approche géniale.
Nit

1
@Nit C'est un méta-post sans downvotes, qui est essentiellement le fonctionnement du consensus communautaire sur SE (au moins sur PPCG). Si vous n'êtes pas d'accord, vous pouvez voter contre cette réponse ou proposer une alternative. Cela étant dit, je ferai probablement un méta-post séparé, en particulier sur les défis de complexité de kolmogorov, car cela revient souvent.
Martin Ender

@Nit Done. N'hésitez pas à venir en discuter sur meta.
Martin Ender

La conversion de gif semblait plus courte.
jimmy23013

5

Mathematica, 217 177 176 166 octets

Voici un début:

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

Moins de golf:

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

Le code QR est codé dans un numéro de base 36. Bien sûr, je pouvais le coder en ASCII étendu (base 256), mais cela ne ferait que raccourcir la chaîne de 30 octets, et je ne suis pas sûr de pouvoir faire la conversion au prix de beaucoup moins que cela.

Bien sûr, c'est Mathematica, donc il y a aussi le 63 octets

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

mais je suppose que c'est une échappatoire standard. ;) (Cela produit un code QR différent de celui du défi, donc je suppose que le code QR n'est pas unique?)


1
Oui, il existe plusieurs façons de coder la même chaîne dans le code QR, par exemple en utilisant différents niveaux de vérification d'erreurs, schéma de codage, image de masquage, etc.
kennytm

FromDigits? Vous pouvez utiliser à la 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2place.
kennytm

@KennyTM oh wow, astuce intéressante. Merci :) Je pense qu'avec cela, la base 256 n'en vaut vraiment pas la peine (j'aurais besoin des deux ToCharacterCodeet FromDigitsensuite.)
Martin Ender

3

Matlab 545 octets

nouvel An

Codé en dur dans un travail manuel minutieux et sans aucune compression / conversation intégrée . Je sais que ce n'est toujours pas aussi bon que les autres réponses mais je suis toujours heureux =)

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

Plus illisible (la version 545 actuelle):

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

Nous créons une matrice nulle 31 x 31, mais y accédons en tant que vecteur pour définir toutes les cellules avec les indices de bà 1. Les astuces que j'ai utilisées étaient la notation d'entiers consécutifs (comme [1,2,3,4] = 1:4) et la suppression d'un des 100 chiffres en ajoutant un scalaire à chaque valeur du vecteur.

Voyons voir si quelqu'un peut battre ça =)


donc je n'ai pas lu le mot unreadablecorrectement ... certainement lu readable. Je l'ai vu juste après l'avoir suggéré et j'espérais que celui qui a lu mon montage l'a rejeté, mais ils l'ont aussi manqué apparemment. désolé pour le mauvais montage ...
pseudonym117

Cela n'a pas vraiment d'importance à mon humble avis, je voulais juste inclure la première version car il est plus facile de s'y référer dans l'explication.
flawr

2

Bash, 206 252 257 octets

L'utilisation de la convertcommande intégrée à imagemagickpermet d'économiser 46 octets supplémentaires.

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

Convertit l' pbmimage encodée en base64 en une pngimage avec imagemagick's convert.

Vous devrez peut-être ajuster le decode (-d)paramètre à votre base64binaire spécifique . Testé sur mon Ubuntu 14.04 LTS.

Enregistré 5 octets en utilisant <<</ ici-chaîne .

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

Ancienne version (257 octets):
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

Juste une simple chaîne de commandes shell qui écrit le pngfichier encodé en base64 dans stdin base64qui le décode à cause du -ddrapeau et écrit sa sortie standard dans newyear.png.


peut probablement enregistrer des caractères avec quelque chose comme, base64 -d>newyear.png<<<[the long string]mais je ne suis pas sur une machine linux rn et je ne sais pas quel espace est obligatoire
undergroundmonorail

Confirmé de fonctionner avec base64 -d>newyear.png<<<[base64 string]Ubuntu 14.04.
PurkkaKoodari

Si vous allez utiliser le code suggéré, modifiez simplement l'en-tête de réponse à quelque chose de spécifique comme Bash, Ksh ou Zsh. Shell en général (comme Sh, Ash ou Dash compatible POSIX) ne prend pas en charge la syntaxe ici-chaîne .
manatwork

Si nous pouvons utiliser des routines netpbm, nous pouvons nourrir le bitmap compressé et perdre 40 octets: echo UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA == | base64 -d | pnmtopng> newyear.png
swstephe

@manatwork Juste édité, devrait fonctionner sur Bash comme je l'ai testé sur mon téléphone Android.
GiantTree

1

Python 2 + PIL, 216 215

Fondamentalement, un portage de la solution 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

Outils Shell communs + 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

Un peu compliqué , mais plus court que l'autre réponse shell .

  • Base64 convertit de base64 en base 256 (ASCII étendu)
  • xxd convertit en hexadécimal
  • tr fait un hex en majuscule, convient pour dc
  • dc lit l'hex et imprime une chaîne binaire de 1 et de 0
  • tr supprime \ et les espaces
  • le pli fait des lignes de 21 caractères (21 pixels) de long
  • Cette sortie, ainsi que P1\n21 21le format PBM P1
  • convert (Imagemagick) le convertit en .png avec une bordure de 5 pixels:

entrez la description de l'image ici

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.