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
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
690
クソアプリハッカソン
ryomm
0
150
万年筆のスゝメ
ryomm
0
150
Other Decks in Programming
See All in Programming
サプライチェーン攻撃対策「層を重ねて落ちない壁」を10日間で組み上げた話 #TechLeadConf2026
kashewnuts
1
320
GitHub Copilot CLIのいいところ
htkym
2
490
プラグインで拡張される Context をtype-safe にする難しさと設計判断
kazupon
2
240
oxlintはeslint/typescript-eslintを置き換えられるのか
shomafujita
2
110
次世代リンターで探る、tsgo 時代における型認識カスタムルールの現実解
ytakahashii
1
720
いつか誰かが、と思っていた フロントエンド刷新5年間の実践知
kiichisugihara
1
290
エラー処理の温故知新 / history of error handling technic
ryotanakaya
7
1.9k
Agentic UI in the Frontend: Architectures with Open Standards @JAX 2026 in Mainz
manfredsteyer
PRO
0
120
AIエージェントの隔離技術の徹底比較
kawayu
0
380
Kubernetesを使わない環境にもCloud Nativeなデプロイを実現する / Enabling Cloud Native deployments without the complexity of Kubernetes
linyows
3
440
AI Agent と正しく分析するための環境作り
yoshyum
2
570
関係性から理解する"同一性"の型用語たち
pvcresin
2
310
Featured
See All Featured
Paper Plane (Part 1)
katiecoart
PRO
0
7.7k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
250
Scaling GitHub
holman
464
140k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
160
Context Engineering - Making Every Token Count
addyosmani
9
890
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
140
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.5k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Thoughts on Productivity
jonyablonski
76
5.2k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
240
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
180
The SEO Collaboration Effect
kristinabergwall1
1
450
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ͷಉ৭ϒϩοΫʹͳ͍ͬͯΔ͔ ϑΝΠϯμʔύλʔϯʹࣅ͍ͯΔ ໌҉Ϟδϡʔϧͷൺ
͜ΕͲ͏ͬͯ ը૾ʹ͢Δ…ʁ