QR 코드로 출력 2015


15

임무는 간단합니다. QR 코드로 숫자 2015를 출력 newyear.png하고 PNG 형식으로 이름이 지정된 파일에 씁니다 . 코드는 하루 종일 유효해야하므로 현재 연도를 사용하지 않아야합니다.

텍스트 인 QR 코드는 다음과 같습니다.

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

작성된 결과 newyear.png에는 흰색 5 픽셀 테두리와 1 픽셀 크기의 점이있는 QR 코드가 포함되어야합니다. QR 코드 이외의 것을 포함해서는 안됩니다.


1
하드 코딩 될 수 있습니까, 아니면 qr 코드를 생성해야합니까?
undergroundmonorail

7
이것이 이미지 출력이 아닌 아스키 아트 출력이라면 더 많은 답변이 올 것입니다.
Optimizer

6
코드가 오류없이 정확하게 정확해야합니까, 아니면 올바르게 스캔하기에 충분합니까? 또한,이하는 (당신이 픽셀을 많이 플립 수 있으며, 그들은 여전히 작동합니다.거야 있도록 QR 코드는, 고의적 중복 및 오류 정정을 많이 가지고) PNG로, 또는 우리가 다른 이미지 포맷을 사용할 수 있습니다 (내가 생각 해요 특히 PBM 에 대해 )?
Ilmari Karonen

답변:


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아래 프로그램을 사용하면 호출 됩니다. PNGOUT을 실행 한 후이 이미지의 길이는 175 바이트입니다. "버전 1"QR 코드에서 "높은"오류 수정 레벨을 사용하면 데이터를 손상시키지 않고 데이터 부분에서 최대 8 픽셀을 수정할 수 있습니다. 약간의 수동 시행 착오로 위에서 제시 한 173 바이트로 더 줄일 수 있습니다. 더 작을 수도 있지만 모든 조합을 소진하려면 208 C 8 ~ 7.5 × 10 13 점검이 필요합니다.


모든 조합을 생성하는 Rust (0.13.0-nightly (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
내가 본 주요 문제는 제출물 자체가 프로그래밍 언어로 작성되지 않았다는 것입니다 .
Martin Ender 2014

4
@ MartinBüttner 선택된 소수의 사람들의 주관적인 의견입니다. 즉, 파일을 얻는 방법이 프로그래밍되었으므로 이것이 완전히 유효한 제출이라고 말할 것입니다. 또한 이것은 놀라운 멋진 접근 방법입니다.
Nit

1
@Nit 다운 보트가없는 메타 게시물로, 기본적으로 커뮤니티 합의가 SE (적어도 PPCG)에서 작동하는 방식입니다. 동의하지 않을 경우 해당 답변을 내리거나 대안을 제공 할 수 있습니다. 즉, 아마도 콜 모고 로프 복잡성 문제에 대해 별도의 메타 포스트를 만들 것입니다.
Martin Ender 2014

@ 니트 . 메타에 대해 언제든지 논의하십시오.
Martin Ender

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

FromDigits? 36^^fl6ibg25c8z00uef53p4657dgd6hjzg41e5joead1qgz0l2xchqgso5r1a51v5no4zkw9v22okklg0cymmy2대신 사용할 수 있습니다 .
kennytm

@KennyTM 오 와우, 깔끔한 트릭. 주셔서 감사합니다 :) 내가 그와 생각,베이스 (256)는 (I 모두 필요할 것없는 가치가 정말 ToCharacterCodeFromDigits다음.)
마틴 청산

3

Matlab 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와는 상관없이 설명에서 참조하기 쉽기 때문에 첫 번째 버전을 포함하고 싶었습니다.
flawr

2

배쉬, 206252257 바이트

convert번들로 제공되는 명령을 사용 imagemagick하면 46 바이트가 더 절약됩니다.

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

변환 base64 인코딩 pbm(A)에 이미지 png와 이미지 imagemagickconvert.

decode (-d)매개 변수를 특정 base64바이너리 에 맞게 조정해야 할 수도 있습니다 . 내 우분투 14.04 LTS에서 테스트되었습니다.

<<</ here-string 을 사용하여 5 바이트를 절약했습니다 .

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

이전 버전 (257 바이트) :
echo iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeAQMAAAAB/jzhAAAABlBMVEX///8AAABVwtN+AAAAX0lEQVQI12PACdi/7G9gYJFUaGBgvaIHJG6CiMvrgGJyCxoY2H/tBxJ3rgIVekxnYGCU9WtgYDokBWSFezcwMPA/ARrwZwMDA4vwUwYG1nuTYMRdP6CYjDRQ9q8fbrsBLRkaYOOP83wAAAAASUVORK5CYII=|base64 -d > newyear.png

base64로 인코딩 된 png파일을 stdin에 기록하는 간단한 쉘 명령 체인 base64-d플래그 때문에 파일 을 디코딩 하고 stdout을 newyear.png에 기록합니다.


수 아마도 같은 문자로 저장 base64 -d>newyear.png<<<[the long string]난 리눅스 머신 RN에서 아니에요 그리고 난이 필수 인 공백 모르지만
undergroundmonorail

base64 -d>newyear.png<<<[base64 string]우분투 14.04 에서 작동하도록 확인했습니다 .
PurkkaKoodari

제안 된 코드를 사용하려면 Bash, Ksh 또는 Zsh와 같은 특정 답변 제목을 편집하십시오. 일반적으로 쉘 (POSIX 호환 Sh, Ash 또는 Dash와 같은)은 here-string 구문을 지원하지 않습니다 .
manatwork

우리가 netpbm 루틴을 사용할 수 있다면, 우리는 압축 된 비트 맵을 공급하고 40 바이트 잃을 수 : 에코 UDQKMzEgMzEKAAAAAAAAAAAAAAAAAAAAAAAAAAAH95 / ABBBQQAXWV0AF0VdABdFXQAQQEEAH9V / AAAWAAAUzMUADqtLABbv0QAcMPAAH1JSAAADwAAfxbUAEFDwABdCUgAXSfAAF1W1ABBMdwAf0FUAAAAA AAAAAAAAAAAAAAAAAAAAAAA을 == | base64로 -d | pnmtopng> newyear.png
swstephe

@manatwork 방금 편집 했으므로 안드로이드 폰에서 테스트했을 때 Bash에서 작동해야합니다.
GiantTree

1

파이썬 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

공통 쉘 도구 + 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에서 base 256 (확장 ASCII)으로 변환
  • xxd는 16 진수로 변환
  • tr은 16 진 대문자를 DC에 적합하게 만듭니다.
  • dc는 16 진수를 읽고 1과 0의 이진 문자열을 인쇄합니다
  • tr은 \와 공백을 제거합니다
  • 접기는 21 자 (21 픽셀) 길이의 선을 만듭니다.
  • 이 출력 P1\n21 21PBM P1 형식 과 함께
  • convert (Imagemagick)는 이것을 5 픽셀 경계로 .png로 변환합니다.

여기에 이미지 설명을 입력하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.