เอาท์พุท 2015 เป็นรหัส QR


15

ภารกิจง่าย เพียงแค่เอาท์พุทหมายเลข 2015 เป็นรหัส QR แล้วเขียนลงในไฟล์ที่มีชื่อnewyear.pngในรูปแบบ PNG รหัสต้องถูกต้องทุกวันดังนั้นบางทีคุณอาจไม่ใช้ปีปัจจุบัน

รหัส QR เนื่องจากข้อความดูเหมือนว่านี้:

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

ผลลัพธ์ที่เขียนnewyear.pngจะต้องมีรหัส QR นั้นที่มีเส้นขอบสีขาว 5 พิกเซลและจุดขนาดพิกเซลหนึ่งจุด ต้องไม่มีสิ่งใดนอกจากรหัส QR


1
มันสามารถเป็น hardcoded หรือคุณต้องสร้างรหัส qr?
undergroundmonorail

7
จะมีคำตอบเพิ่มเติมอีกมากมายหากเป็นผลลัพธ์จาก ASCII Art และไม่ได้แสดงผลภาพ
เครื่องมือเพิ่มประสิทธิภาพ

6
รหัสจะต้องถูกต้องอย่างแน่นอนโดยไม่มีข้อผิดพลาดหรือว่ามันเพียงพอที่จะสแกนอย่างถูกต้อง? (รหัส QR มีจำนวนมากซ้ำซ้อนโดยเจตนาและการแก้ไขข้อผิดพลาดดังนั้นคุณสามารถพลิกพิกเซลจำนวนมากและพวกเขาจะยังคงทำงานได้) นอกจากนี้ต้องมี PNG หรือเราสามารถใช้รูปแบบภาพอื่น ๆ ได้ (ฉันคิดว่า โดยเฉพาะเกี่ยวกับPBMที่นี่)
Ilmari Karonen

คำตอบ:


12

ไฟล์ Raw, 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ซึ่งฉันจะไม่ทำ;)


โปรแกรม Rust (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
ปัญหาหลักที่ฉันเห็นที่นี่คือการส่งของคุณเองไม่ได้เขียนในภาษาการเขียนโปรแกรมภาษาการเขียนโปรแกรม
Martin Ender

4
@ MartinBüttnerนั่นเป็นความเห็นส่วนตัวของคนไม่กี่คนที่เลือก อย่างที่บอกไปแล้วว่าไฟล์ที่ได้รับนั้นได้รับการตั้งโปรแกรมดังนั้นฉันจึงบอกว่านี่เป็นไฟล์ที่ถูกต้องสมบูรณ์ นอกจากนี้ยังเป็นวิธีที่น่ากลัว frigging
Nit

1
@Nit มันเป็นเมตาโพสต์ที่ไม่มี downvotes ซึ่งโดยพื้นฐานแล้วเป็นวิธีที่ฉันทามติของชุมชนทำงานกับ SE (อย่างน้อยก็ใน PPCG) หากคุณไม่เห็นด้วยคุณสามารถลงคะแนนคำตอบนั้นหรือให้ทางเลือกอื่น ที่ถูกกล่าวว่าฉันอาจจะทำเมตาโพสต์แยกต่างหากโดยเฉพาะเกี่ยวกับความท้าทายที่ซับซ้อน kolmogorov เช่นนี้จะเกิดขึ้นมาก
Martin Ender

@ ทำเสร็จแล้ว อย่าลังเลที่จะพูดคุยเกี่ยวกับเรื่องนี้ในเมตาดาต้า
Martin Ender

การแปลงจาก gif ดูสั้นลง
jimmy23013

5

Mathematica, 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 มันไม่คุ้มค่า (ฉันจำเป็นต้องใช้ทั้งToCharacterCodeและFromDigitsแล้ว.)
มาร์ตินเอนเดอร์

3

Matlab 545 Bytes

ปีใหม่

ฮาร์ดโค้ดในงานที่ต้องใช้ความระมัดระวังและไม่มีการบีบอัด / สนทนาสตริงในตัวโดยไม่ต้องบีบอัดแฟนซีฉันรู้ว่ามันยังไม่ดีเท่าคำตอบอื่น ๆ แต่ฉันก็ยังมีความสุข =)

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 แต่เข้าถึงมันเป็นเวกเตอร์เพื่อตั้งค่าเซลล์ทั้งหมดด้วยดัชนีของ b1การ เทคนิคที่ฉันใช้คือสัญกรณ์ของจำนวนเต็มต่อเนื่อง (เช่น[1,2,3,4] = 1:4) และลบหนึ่งหลัก 100 โดยเพิ่มเซนต์คิตส์และเนวิสให้กับทุกค่าของเวกเตอร์

มาดูกันว่าใครจะสามารถเอาชนะได้ =)


ดังนั้นผมจึงไม่ได้อ่านคำunreadableได้อย่างถูกต้อง ... readableอ่านแน่นอน เห็นว่าหลังจากแนะนำแล้วและหวังว่าใครก็ตามที่อ่านการแก้ไขของฉันจะปฏิเสธ แต่พวกเขาก็พลาดเช่นกัน ขออภัยเกี่ยวกับการแก้ไขที่ไม่ดี ...
นามแฝง

ไม่เกี่ยวข้องกับ IMHO เพียงต้องการรวมรุ่นแรกไว้ด้วยเพราะง่ายต่อการอ้างถึงในการอธิบาย
ข้อบกพร่อง

2

Bash, 206 252 257ไบต์

การใช้convertคำสั่งที่บันเดิลimagemagickช่วยให้ประหยัดได้มากขึ้น 46 ไบต์

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

แปลงpbmรูปภาพที่เข้ารหัส base64 ไปเป็นpngรูปภาพด้วยimagemagickconvert 's

คุณอาจต้องปรับdecode (-d)พารามิเตอร์ให้เป็นbase64ไบนารีเฉพาะของคุณ ทดสอบกับ Ubuntu 14.04 LTS ของฉัน

ที่บันทึกไว้ 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

เพียงเชนคำสั่งเชลล์แบบง่ายที่เขียนpngไฟล์ที่เข้ารหัส base64 ลงใน stdin ของbase64มันจะถอดรหัสเพราะ-dแฟล็กและเขียน stdout ไปยัง newyear.png


อาจจะสามารถบันทึกตัวละครด้วยสิ่งที่ชอบbase64 -d>newyear.png<<<[the long string]แต่ฉันไม่ได้อยู่ที่เครื่องลินุกซ์ rn และฉันไม่ทราบว่าช่องว่างที่บังคับ
undergroundmonorail

ยืนยันว่าจะทำงานกับbase64 -d>newyear.png<<<[base64 string]บน Ubuntu 14.04
PurkkaKoodari

หากคุณกำลังจะใช้รหัสที่แนะนำเพียงแก้ไขหัวข้อคำตอบไปยังสิ่งที่เฉพาะเจาะจงเช่น Bash, Ksh หรือ Zsh เชลล์โดยทั่วไป (เช่น Sh, Ash หรือ Dash ที่รองรับ POSIX) ไม่รองรับไวยากรณ์ของสตริงที่นี่
จัดการการผลิต

ถ้าเราสามารถใช้การปฏิบัติ 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

เครื่องมือเชลล์สามัญ + 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 ทำให้ hex ตัวพิมพ์ใหญ่เหมาะสำหรับ dc
  • dc อ่าน hex และพิมพ์สตริงไบนารีของ 1s และ 0s
  • tr ลบ \ และช่องว่างออก
  • การพับทำให้เส้นยาว 21 ตัวอักษร (21 พิกเซล)
  • ผลลัพธ์นี้พร้อมกับP1\n21 21เป็นรูปแบบ PBM P1
  • แปลง (Imagemagick) แปลงเป็น. png ด้วยเส้นขอบ 5 พิกเซล:

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.