Upgrade to Pro — share decks privately, control downloads, hide ads and more …

iOSでQRコード生成奮闘記

Ryomm
March 04, 2025

 iOSでQRコード生成奮闘記

2025.03.04 集まれSwift好き!Swift愛好会 vol.92 @DeNA

Ryomm

March 04, 2025
Tweet

More Decks by Ryomm

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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
  4. func qrCode(of binary: String) -" UIImage? { guard let bint

    = BInt(binary, radix: 16), let string = String(byte: bint.getBytes(), encoding: .utf16BigEndian) else { return nil } let transform = CGAffineTransform(scaleX: 10, y: 10) guard let data = string.data(using: encoding), 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) }
  5. func qrCode(of binary: String) -" UIImage? { guard let bint

    = BInt(binary, radix: 16), let string = String(byte: bint.getBytes(), encoding: .utf16BigEndian) else { return nil } let transform = CGAffineTransform(scaleX: 10, y: 10) guard let data = string.data(using: encoding), 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 qrCode(of binary: String) -" UIImage?
  6. func qrCode(of binary: String) -" UIImage? { guard let bint

    = BInt(binary, radix: 16), let string = String(byte: bint.getBytes(), encoding: .utf16BigEndian) else { return nil } let transform = CGAffineTransform(scaleX: 10, y: 10) guard let data = string.data(using: encoding), 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 qrCode(of binary: String) -" UIImage?
  7. func qrCode(of binary: String) -" UIImage? { guard let bint

    = BInt(binary, radix: 16), let string = String(byte: bint.getBytes(), encoding: .utf16BigEndian) else { return nil } let transform = CGAffineTransform(scaleX: 10, y: 10) guard let data = string.data(using: encoding), 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) }
  8. String(16ਐ਺) "6e79dc68" BInt(10ਐ਺) 1853480040 String “㧅`“ Data 6e79616e ṖͷόΠφϦX import

    BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000]
  9. String(16ਐ਺) "6e79dc68" BInt(10ਐ਺) 1853480040 Data 6e79616e ṖͷόΠφϦX String “㧅`“ Bytes

    / [UInt8] [01101110, 01111001, 11011100, 1101000] import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian)
  10. String(16ਐ਺) "6e79dc68" ṖͷόΠφϦX import BigNumber let binary = "6e79dc68" let

    bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) Data 6e79616e
  11. String(16ਐ਺) "6e79dc68" BInt(10ਐ਺) 1853480040 ṖͷόΠφϦX 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ import BigNumber let binary

    = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) Data 6e79616e
  12. String(16ਐ਺) "6e79dc68" BInt(10ਐ਺) 1853480040 ṖͷόΠφϦX 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ Bytes / [UInt8] [01101110,

    01111001, 11011100, 1101000] 2ਐ਺Ͱ8Ϗοτ·Ͱ֨ೲͰ͖Δܕ import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) 1101110011110011101110001101000 Data 6e79616e
  13. String(16ਐ਺) "6e79dc68" BInt(10ਐ਺) 1853480040 ṖͷόΠφϦX 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ Bytes / [UInt8] [01101110,

    01111001, 11011100, 1101000] 2ਐ਺Ͱ8Ϗοτ·Ͱ֨ೲͰ͖Δܕ import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) String “㧅`“ Data 6e79616e
  14. BInt(10ਐ਺) 1853480040 Data 6e79616e ṖͷόΠφϦX 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ String(16ਐ਺) "6e79dc68" String “㧅`“

    Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] 2ਐ਺Ͱ8Ϗοτ·Ͱ֨ೲͰ͖Δܕ import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian)
  15. BInt(10ਐ਺) 1853480040 Data 6e79616e ṖͷόΠφϦX 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ String(16ਐ਺) "6e79dc68" String “㧅`“

    Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] 2ਐ਺Ͱ8Ϗοτ·Ͱ֨ೲͰ͖Δܕ import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian)
  16. Data 6e79616e ṖͷόΠφϦX String(16ਐ਺) "6e79dc68" String “㧅`“ Bytes / [UInt8]

    [01101110, 01111001, 11011100, 1101000] 2ਐ਺Ͱ8Ϗοτ·Ͱ֨ೲͰ͖Δܕ BInt(10ਐ਺) 1853480040 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) iOS17·Ͱ͸͜ΕͰ໰୊ͳ͔ͬͨᴷᴷᴷᴷᴷᴷ
  17. BInt(10ਐ਺) 1853480040 String nil Data 6e79616e ṖͷόΠφϦX 8όΠτͷ੔਺Λ֨ೲ͢Δσʔλܕ String(16ਐ਺) "6e79dc68"

    import BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bing?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] 2ਐ਺Ͱ8Ϗοτ·Ͱ֨ೲͰ͖Δܕ wow
  18. Special thanks: omochimetal͞Μ 6e79 dc68 αϩήʔτϖΞͷยׂΕ let binary = "6e79dc68"

    /* ... */ let string = String(bytes: bytes!, encoding: .utf16BigEndian) αϩήʔτϖΞ ্Ґαϩήʔτ D800ʙDBFF ԼҐαϩήʔτ DC00ʙDFFF + αϩήʔτϖΞҎ֎Ͱσίʔυࣦഊ͠ͳ͍ ΋͏Ұํ͸ʁ
  19. σίʔυࣦഊ࣌ͷ஋ String nil String “㧅`“ CoreFoundation swift-foundation let binary =

    "6e79dc68" /* ... */ let string = String(bytes: bytes!, encoding: .utf16BigEndian)
  20. BInt(10ਐ਺) 1853480040 String nil Data 6e79616e ṖͷόΠφϦX String(16ਐ਺) "6e79dc68" import

    BigNumber let binary = "6e79dc68" let bint = BInt(binary, radix: 16) let bytes = bing?.getBytes() let string = String(bytes: bytes!, encoding: .utf16BigEndian) let data = string?.data(using: .utf16BigEndian) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] ԿͰΤϯίʔυ͞Εͨ΋ͷ͔ Θ͔Βͳ͍ ͳΜͰ΋͍͍͔Β Ұ୴σίʔυ͍ͨ͠
  21. let binary = "6e79dc68" let bint = BInt(binary, radix: 16)

    let bytes = bint?.getBytes() let string: String? = if let str = String(bytes: bytes!, encoding: .utf16BigEndian) { str } else if let str = String(bytes: bytes!, encoding: .utf16LittleEndian) { str } else if let str = String(bytes: bytes!, encoding: .utf16) { str } else if let str = String(bytes: bytes!, encoding: .isoLatin1) { str } else { nil }
  22. let binary = "6e79dc68" let bint = BInt(binary, radix: 16)

    let bytes = bint?.getBytes() let string: String? = if let str = String(bytes: bytes!, encoding: .utf16BigEndian) { str } else if let str = String(bytes: bytes!, encoding: .utf16LittleEndian) { str } else if let str = String(bytes: bytes!, encoding: .utf16) { str } else if let str = String(bytes: bytes!, encoding: .isoLatin1) { str } else { nil } ૯౰ͨΓ େ࡞ઓ
  23. BInt(10ਐ਺) 1853480040 String ṖͷόΠφϦX import BigNumber let binary = "6e79dc68"

    let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string: String? = if let str = String( bytes: bytes!, encoding: .???) { str } else { ... } let data = string?.data(using: .???) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] Data 6e79616e String(16ਐ਺) "6e79dc68"
  24. BInt(10ਐ਺) 1853480040 String ṖͷόΠφϦX import BigNumber let binary = "6e79dc68"

    let bint = BInt(binary, radix: 16) let bytes = bint?.getBytes() let string: String? = if let str = String( bytes: bytes!, encoding: .???) { str } else { ... } let data = string?.data(using: .???) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] Data 6e79616e String(16ਐ਺) "6e79dc68" ͳΜͰ΋͍͍͔Β Ұ୴σίʔυ͍ͨ͠
  25. BInt(10ਐ਺) 1853480040 String ṖͷόΠφϦX import BigNumber let binary = "6e79dc68"

    let bint = BInt(binary, radix: 16) let bytes = bing?.getBytes() let string: String? = if let str = String( bytes: bytes!, encoding: .???) { str } else { ... } let data = string?.data(using: .???) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] Data 6e79616e String(16ਐ਺) "6e79dc68" ͳΜͰ΋͍͍͔Β Ұ୴σίʔυ͍ͨ͠ ͜Ε͍Δʁ
  26. BInt(10ਐ਺) 1853480040 ṖͷόΠφϦX import BigNumber let binary = "6e79dc68" let

    bint = BInt(binary, radix: 16) let bytes: [UInt8] = bint?.getBytes() let data: Data = Data(bytes) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] Data 6e79616e String(16ਐ਺) "6e79dc68"
  27. BInt(10ਐ਺) 1853480040 ṖͷόΠφϦX import BigNumber let binary = "6e79dc68" let

    bint = BInt(binary, radix: 16) let bytes: [UInt8] = bing?.getBytes() let data: Data = Data(bytes) Bytes / [UInt8] [01101110, 01111001, 11011100, 1101000] Data 6e79616e String(16ਐ਺) "6e79dc68"
  28. func qrCode(of binary: String) -" UIImage? { guard let bint

    = BInt(binary, radix: 16) else { return nil } let bytes: [UInt8] = bint.getBytes() let data: Data = Data(bytes) let transform = CGAffineTransform(scaleX: 10, y: 10) 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) }
  29. 23ίʔυͷόʔδϣϯ όʔδϣϯ1 21×21 (M)14byte όʔδϣϯ10 57×57 (M)213byte όʔδϣϯ40 177×177 (M)2,331byte

    όʔδϣϯ5 37×37 (M)84byte ࢀߟ: https://www.qrcode.com/about/version.html
  30. 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) }
  31. ʂ

  32. 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) }
  33. 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) }
  34. 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) }
  35. ϚεΫύλʔϯ 000 Ϟʔυࢦࣔࢠ (i × j) % 2 + (i

    × j) % 3 XOR = 0100 → 8ϏοτόΠτϞʔυͩʂ (͓·͚)