Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
QRコードの仕様ってn種類あんねん
Search
Ryomm
September 20, 2025
Programming
11
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
QRコードの仕様ってn種類あんねん
2025.09.20 iOSDC Japan 2025
Ryomm
September 20, 2025
More Decks by Ryomm
See All by Ryomm
Bring your app’s core features to users with App Intents とか App Intents 関連の要約
ryomm
1
710
クソアプリハッカソン
ryomm
0
150
万年筆のスゝメ
ryomm
0
150
Other Decks in Programming
See All in Programming
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.6k
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
180
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
430
AI がコードを書く時代における新卒エンジニアの仕事風景 (2026) / New Graduate Engineers in the Era of AI Coding (2026)
sushichan044
0
240
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
110
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
140
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
620
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
0
160
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.1k
AIが無かった頃の素敵な出会いの話
codmoninc
1
270
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
410
Featured
See All Featured
Everyday Curiosity
cassininazir
0
260
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
BBQ
matthewcrist
89
10k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Darren the Foodie - Storyboard
khoart
PRO
3
3.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Leo the Paperboy
mayatellez
8
1.9k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
220
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.4k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
610
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
200
Transcript
QRίʔυͷ༷ͬͯnछྨ͋ΜͶΜ 2025.09.20 iOSDC Japan 2025 Ryomm / Ryoko Matsusaka
Ryomm / Ryoko Matsusaka ͦͷଞ: Ryomm : @__ryomm iOSΞϓϦΤϯδχϟ
QRίʔυ(ג)σϯιʔΣʔϒͷొඪͰ͢ QRίʔυΛੜ͍ͨ͠
func qrCode(data: Data?) -" UIImage? { let transform = CGAffineTransform(scaleX:
10, y: 10) guard let data, let filter = CIFilter(name: “CIQRCodeGenerator”, parameters: ["inputMessage": data, "inputCorrectionLevel": "Q"]), let ciImage = filter.outputImage?.transformed(by: transform) let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) } https://developer.apple.com/documentation/coreimage/cifilter https://developer.apple.com/documentation/coreimage/ciqrcodegenerator
func qrCode(data: Data?) -" UIImage? { let transform = CGAffineTransform(scaleX:
10, y: 10) guard let data, let filter = CIFilter(name: “CIQRCodeGenerator”, parameters: ["inputMessage": data, "inputCorrectionLevel": "Q"]), let ciImage = filter.outputImage?.transformed(by: transform) let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) } https://developer.apple.com/documentation/coreimage/cifilter https://developer.apple.com/documentation/coreimage/ciqrcodegenerator QRίʔυʹؚΊΔσʔλ ޡΓగਖ਼Ϩϕϧ
func qrCode(data: Data?) -" UIImage? { let transform = CGAffineTransform(scaleX:
10, y: 10) guard let data, let filter = CIFilter(name: “CIQRCodeGenerator”, parameters: ["inputMessage": data, "inputCorrectionLevel": "Q"]), let ciImage = filter.outputImage?.transformed(by: transform) let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) } https://developer.apple.com/documentation/coreimage/cifilter https://developer.apple.com/documentation/coreimage/ciqrcodegenerator
QRίʔυͷ༷ͬͯnछྨ͋ΜͶΜ
࠷ۙͷMaaSք۾
࠷ۙͷMaaSք۾
όʔδϣϯ
όʔδϣϯ όʔδϣϯ1 2121 M14byte όʔδϣϯ10 5757 M213byte όʔδϣϯ40 177177 M2,331byte
όʔδϣϯ5 3737 M84byte ࢀߟ: https://www.qrcode.com/about/version.html
func qrCode(data: Data?) -" UIImage? { let transform = CGAffineTransform(scaleX:
10, y: 10) guard let data, let filter = CIFilter(name: “CIQRCodeGenerator”, parameters: ["inputMessage": data, "inputCorrectionLevel": "Q"]), let ciImage = filter.outputImage?.transformed(by: transform) let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) }
func qrCode(data: Data?) -" UIImage? { let transform = CGAffineTransform(scaleX:
10, y: 10) guard let data, let filter = CIFilter(name: “CIQRCodeGenerator”, parameters: ["inputMessage": data, "inputCorrectionLevel": "Q"]), let ciImage = filter.outputImage?.transformed(by: transform) let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) } όʔδϣϯࢦఆ Ͱ͖ͳ͘Ͷ…ʁ ʁ ͳΜ͔উखʹ ৭ΜͳόʔδϣϯͰ ੜ͞ΕͯΔ͠…
ͳΜ͔উखʹ ৭ΜͳόʔδϣϯͰ ੜ͞ΕͯΔ͠…
ͳΜ͔উखʹ ৭ΜͳόʔδϣϯͰ ੜ͞ΕͯΔ͠… ʂ
Data 1234123412 Data 123…………..234 ʂ
func qrCodeVersion5(of binary: String) -" UIImage? { guard let bint
= BInt(binary, radix: 16) else { return nil } let bytes: [UInt8] = bint.getBytes() let maxBinaryLength = 84 let shortage = maxBinaryLength - bytes.count if shortage > 0 { bytes.insert(contentsOf: Array(repeating: 0, count: shortage), at: 0) } let data: Data = Data(bytes) guard let QRFilter = CIFilter(name: ”CIQRCodeGenerator”, parameters: ["inputMessage": data]), let ciImage = QRFilter.outputImage?.transformed(by: transform), let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) }
func qrCodeVersion5(of binary: String) -" UIImage? { guard let bint
= BInt(binary, radix: 16) else { return nil } let bytes: [UInt8] = bint.getBytes() let maxBinaryLength = 84 let shortage = maxBinaryLength - bytes.count if shortage > 0 { bytes.insert(contentsOf: Array(repeating: 0, count: shortage), at: 0) } let data: Data = Data(bytes) guard let QRFilter = CIFilter(name: ”CIQRCodeGenerator”, parameters: ["inputMessage": data]), let ciImage = QRFilter.outputImage?.transformed(by: transform), let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) }
func qrCodeVersion5(of binary: String) -" UIImage? { guard let bint
= BInt(binary, radix: 16) else { return nil } let bytes: [UInt8] = bint.getBytes() let maxBinaryLength = 84 let shortage = maxBinaryLength - bytes.count if shortage > 0 { bytes.insert(contentsOf: Array(repeating: 0, count: shortage), at: 0) } let data: Data = Data(bytes) guard let QRFilter = CIFilter(name: ”CIQRCodeGenerator”, parameters: ["inputMessage": data]), let ciImage = QRFilter.outputImage?.transformed(by: transform), let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) } 0 0 0 0 0ຒΊͰ͞ௐ
func qrCodeVersion5(of binary: String) -" UIImage? { guard let bint
= BInt(binary, radix: 16) else { return nil } let bytes: [UInt8] = bint.getBytes() let maxBinaryLength = 84 let shortage = maxBinaryLength - bytes.count if shortage > 0 { bytes.insert(contentsOf: Array(repeating: 0, count: shortage), at: 0) } let data: Data = Data(bytes) guard let QRFilter = CIFilter(name: ”CIQRCodeGenerator”, parameters: ["inputMessage": data]), let ciImage = QRFilter.outputImage?.transformed(by: transform), let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } return UIImage(cgImage: cgImage) }
ଞʹԿ͔ΕΔ ؾ͕͖ͯͨ͠ ʢ͔͜͜Βझຯʣ
ٖࣅϑϨʔϜ23
ޡΓగਖ਼Ϩϕϧ ϨϕϧL Low 7% ϨϕϧM Medium 15% ϨϕϧQ Quality) 25%
ϨϕϧH High 30% ࢀߟ: https://www.qrcode.com/about/error_correction.html
ޡΓగਖ਼ ϔομʔ ύσΟϯά 1ίʔυϫʔυ8bit σʔλίʔυϫʔυ ޡΓగਖ਼ίʔυϫʔυ શίʔυϫʔυ
ޡΓగਖ਼ σʔλίʔυϫʔυ: 10 / గਖ਼ର: 5 ޡΓగਖ਼ίʔυϫʔυ: 52 10
గਖ਼͢Δίʔυϫʔυͷ2ഒ గਖ਼: 5 / 20 25% (ϨϕϧQ σʔλίʔυϫʔυ ޡΓగਖ਼ίʔυϫʔυ શίʔυϫʔυ
ޡΓగਖ਼ గਖ਼: గਖ਼Մೳ / શίʔυϫʔυ RSϒϩοΫ గਖ਼: 2 / 8
25% గਖ਼: 4 / 16 25%
ޡΓగਖ਼Ϩϕϧ ϨϕϧM ϨϕϧQ ϨϕϧL ϨϕϧH ࣮ࡍ ͜ͷ͘Β͍͍͚Δ
func frameQRCode(data: Data?, image: UIImage) -" UIImage? { let transform
= CGAffineTransform(scaleX: 10, y: 10) guard let data, let filter = CIFilter(name: “CIQRCodeGenerator”, parameters: ["inputMessage": data, "inputCorrectionLevel": "H"]), let ciImage = filter.outputImage?.transformed(by: transform) let cgImage = CIContext().createCGImage(ciImage, from: ciImage.extent) else { return nil } let qrImage = UIImage(cgImage: cgImage) return UIGraphicsImageRenderer(size: qrImage.size).image { context in let qrWidth = context.format.bounds.width let qrHeight = context.format.bounds.height let imageWidth = qrWidth / (dimension + 2) * imageDimension let imageHeight = qrHeight / (dimension + 2) * imageDimension ࢀߟ: https://dev.classmethod.jp/articles/swift-generate-qr-code/
let qrImage = UIImage(cgImage: cgImage) return UIGraphicsImageRenderer(size: qrImage.size).image { context
in let qrWidth = context.format.bounds.width let qrHeight = context.format.bounds.height let imageWidth = qrWidth / (dimension + 2) * imageDimension let imageHeight = qrHeight / (dimension + 2) * imageDimension qrImage.draw(in: CGRect(origin: .zero, size: context.format.bounds.size)) let imageRect = CGRect(x: (qrWidth - imageWidth) / 2, y: (qrHeight - imageHeight) / 2, width: imageWidth, height: imageHeight) image.draw(in: imageRect) } } ࢀߟ: https://dev.classmethod.jp/articles/swift-generate-qr-code/
let qrImage = UIImage(cgImage: cgImage) return UIGraphicsImageRenderer(size: qrImage.size).image { context
in let qrWidth = context.format.bounds.width let qrHeight = context.format.bounds.height let imageWidth = qrWidth / (dimension + 2) * imageDimension let imageHeight = qrHeight / (dimension + 2) * imageDimension qrImage.draw(in: CGRect(origin: .zero, size: context.format.bounds.size)) let imageRect = CGRect(x: (qrWidth - imageWidth) / 2, y: (qrHeight - imageHeight) / 2, width: imageWidth, height: imageHeight) image.draw(in: imageRect) } } ࢀߟ: https://dev.classmethod.jp/articles/swift-generate-qr-code/
͜ΕͲ͜·Ͱ ΕΔΜͩʙʂʁ
0 0 1 1 ׂ23ίʔυ ϔομʔ ύσΟϯά σʔλ Ϟʔυࢦࣔࢠ ;ͭ͏ͷQRίʔυ
3 ׂQRίʔυ ׂQRίʔυ ͜ΕԿ൪ʁ શ෦ͰԿݸʁ ϖʔδ൪߸ ࠷େϖʔδ൪߸ ࿈݁༻IDతͳѻ͍Λ͞Ε͕ͪ ࢀߟ: https://programresource.net/2013/05/04/2193.html ύϦςΟ(্Ґ) ύϦςΟ(ԼҐ)
͋ʙͳΜ͔͜Ε… Ͱ͖ͳ͘ͳͦ͞͏…
͋ʙͳΜ͔͜Ε… Ͱ͖ͳ͘ͳͦ͞͏… CIQRCodeGeneratorͰ Ͳ͏ͬͯϔομʔใ ͍͡ΔΜͩ…ʁ
Ͱ͖·ͤΜʂ
ࢀߟ: https://github.com/zxing-cpp/zxing-cpp
Ϟʔυࢦࣔࢠ ࣈ ӳه߸ 8bit ࣈ
Ϟʔυࢦࣔࢠ ࣈ ӳه߸ 8bit ࣈ “nyan".data(using: .utf8) 1101110 1111001 1100001
1101110
Ϟʔυࢦࣔࢠ ࣈ ӳه߸ 8bit ࣈ “nyan".data(using: .utf8) 1101110 1111001 1100001
1101110 0001 0010 0100 1000 ϔομʔ
όʔδϣϯ 1101110 1111001 1100001 1101110 4byte ޡΓగਖ਼Ϩϕϧ: Q ΄ͳɺόʔδϣϯ1͔ʙ 2121ͷۭͷϚτϦοΫε
ϔομʔ σʔλίʔυϫʔυ
σʔλͷେ͖͞ ϔομʔ 1101110 1111001 1100001 1101110 4byte σʔλ4byteೖͬͯΔͷͶʂ σʔλίʔυϫʔυ 8bit
ऴύλʔϯύσΟϯάύλʔϯ ޡΓగਖ਼Ϩϕϧ: Q όʔδϣϯ: 1ɹ 13byteೖΓ·͢ͳʙ ϔομʔใؚΜͩ༰ྔ
ϔομʔ 1101110 1111001 1100001 1101110 σʔλίʔυϫʔυ
ऴύλʔϯύσΟϯάύλʔϯ
ϔομʔ 1101110 1111001 1100001 1101110 σʔλίʔυϫʔυ
ऴύλʔϯύσΟϯάύλʔϯ ϔομʔ σʔλίʔυϫʔυ 13byte 12bit 4byte σʔλ෦֨ೲՄೳ༰ྔ ऴύλʔϯ 0000 ͪΐ͏Ͳ8bitʹͳΔΑ͏0ຒΊ
ύσΟϯάύλʔϯ 0xEC 0x11 0xEC 0x11 …
ޡΓగਖ਼ ϔομʔ σʔλίʔυϫʔυ ޡΓగਖ਼ίʔυϫʔυ
ϚεΫύλʔϯ 000 (x+y)%2='0 001 y%2='0 010 x%3='0 011 (x+y)%3='0 100
((y/2)+(x/3)%2='0 101 (x*y)%6='0 110 (x*y)%6<3 111 (y+x+((y*x)%3))%2='0
ϚεΫύλʔϯ 000 (x+y)%2='0 001 y%2='0 010 x%3='0 011 (x+y)%3='0 100
((y/2)+(x/3)%2='0 101 (x*y)%6='0 110 (x*y)%6<3 111 (y+x+((y*x)%3))%2='0
ϑΝΠϯμύλʔϯηύϨʔλ ϑΝΠϯμύλʔϯ ҐஔճసΛݕग़ ηύϨʔλ
ΞϥΠϝϯτύλʔϯ ΞϥΠϝϯτύλʔϯ ΈʹΑΔҐஔͣΕΛิਖ਼
λΠϛϯάύλʔϯ λΠϛϯάύλʔϯ Ϟδϡʔϧ࠲ඪΛݕग़
ϑΥʔϚοτใ ޡΓగਖ਼Ϩϕϧ ϚεΫύλʔϯ 2bit 3bit
ޡΓగਖ਼ූ߸ʢBCHූ߸ʣ bchCode(formatInfo, poly: 0x537)
ϑΥʔϚοτใ ޡΓగਖ਼Ϩϕϧ ϚεΫύλʔϯ 2bit 3bit
10bit ޡΓగਖ਼ූ߸ formatBits ^ 0x5412
ϑΥʔϚοτใ
σʔλใ
ϚεΫύλʔϯ 000 (x+y)%2='0 001 y%2='0 010 x%3='0 011 (x+y)%3='0 100
((y/2)+(x/3)%2='0 101 (x*y)%6='0 110 (x*y)%6<3 111 (y+x+((y*x)%3))%2='0
ϚεΫύλʔϯ 000 (x+y)%2='0 001 y%2='0 010 x%3='0 011 (x+y)%3='0 100
((y/2)+(x/3)%2='0 101 (x*y)%6='0 110 (x*y)%6<3 111 (y+x+((y*x)%3))%2='0
ϚεΫύλʔϯ ಉ͡৭ͷϞδϡʔϧ͕࿈ଓ͢Δ͔5ݸҎ্) 22ͷಉ৭ϒϩοΫʹͳ͍ͬͯΔ͔ ϑΝΠϯμʔύλʔϯʹࣅ͍ͯΔ ໌҉Ϟδϡʔϧͷൺ
͜ΕͲ͏ͬͯ ը૾ʹ͢Δ…ʁ