Dinamik QR Kod Üretim Algoritması
QR Code Model 2 kodlama hattını C# ile doğrudan gerçekleştiren yaklaşımı açıklar. Kip ve sürüm seçimi, Reed-Solomon kodları, matris yerleşimi, maskeleme ve dinamik web üretimi ele alınır.
Bir QR kodu oluşturmak ile QR kod standardını gerçeklemek aynı işlem değildir. Hazır bir kütüphaneye metin verip görüntü almak, üretim hattının yalnız son katmanını kullanır. Standartla uyumlu bir kodlayıcı geliştirmek ise veri kipinin seçilmesini, sürüm kapasitesinin hesaplanmasını, Reed-Solomon hata düzeltme kodlarının üretilmesini, modüllerin matrise yerleştirilmesini, sekiz maskeleme seçeneğinin değerlendirilmesini ve sonuç matrisinin kayıpsız biçimde görüntüye dönüştürülmesini gerektirir.
Kişisel web sitemde yıllardır kullandığım QR kod kütüphanesini bu ikinci yaklaşımla geliştirdim. Sayfanın URL değeri çalışma anında kodlanıyor ve QR görüntüsü milisaniye düzeyinde oluşturuluyor. İşlem süresi, pratik kullanımda statik bir görsel dosyasının sunulmasına yakın kaldı. Bu sayede her sayfa için ayrı QR dosyası üretmek, saklamak, adlandırmak ve güncellemek zorunda kalmadım.
Aynı yaklaşımı özgeçmiş belgelerimde de kullandım. Basılı veya PDF biçimindeki belgeyi inceleyen kişi, uzun bir adresi elle yazmadan doğrudan kişisel web siteme geçebildi. Restoran ve kafelerdeki menü kullanımı da QR kodun en doğal uygulamalarından biridir. Buradaki gerçek kazanç, yalnız menünün telefonda açılması değildir. Basılı QR kod aynı kalırken fiyatlar, ürünler ve açıklamalar sunucu tarafında güncellenebilir.
Endüstriyel bir ihtiyacın sonucu
QR Code, Denso bünyesinde Masahiro Hara ve çalışma arkadaşları tarafından otomotiv üretim süreçlerindeki veri taşıma ve hızlı okuma gereksinimine cevap olarak geliştirildi. Geleneksel barkodların tek boyutlu yapısı sınırlı miktarda bilgi taşıyor, üretim hatlarında birden fazla barkodun birlikte kullanılmasını gerektiriyordu. Geliştirme ekibi daha fazla veri taşıyan ve farklı yönlerden hızlı okunabilen iki boyutlu bir sembol üzerinde çalıştı. QR Code 1994 yılında duyuruldu ve ilk önemli kullanım alanlarından biri otomotiv sektöründeki elektronik Kanban süreçleri oldu.
Tasarımın belirleyici yeniliklerinden biri, üç köşede bulunan konum belirleme desenleridir. Ekip, basılı belgelerde yanlışlıkla görülme olasılığı düşük bir siyah-beyaz oran aradı ve "1:1:3:1:1" dizilimini seçti. Tarayıcı bu oranı farklı açılarda tespit ederek sembolün konumunu ve yönünü hızlı biçimde belirleyebildi. QR adındaki Quick Response ifadesi de bu hızlı okuma hedefinden gelir.
QR Code 1997'de AIM, 1999'da Japon endüstri standardı ve 2000'de ISO standardı haline geldi. Denso Wave, standarda uygun QR Code uygulamaları için sahip olduğu patent haklarını kullanmama politikası izledi. Bu karar, teknolojinin belirli bir üreticiye veya ücretli hizmete bağlı kalmadan yayılmasında önemli rol oynadı. Güncel yayımlanmış semboloji standardı ISO/IEC 18004:2024'tür. Standart, veri kodlama yöntemlerinden hata düzeltmeye, sembol yapısından üretim kalitesine kadar bütün temel kuralları tanımlar.
Kütüphanenin teknik konumu
Geliştirdiğim kütüphane, QR biçimine benzeyen özel bir kare desen üretmiyor. QR Code Model 2 kodlama hattını gerçekliyor. Model 2, bugün normal QR kod denildiğinde kastedilen yaygın biçimdir. Sürüm 1'de sembol 21 x 21 modülden oluşur. Her yeni sürümde kenar uzunluğu dört modül artar ve sürüm 40'ta 177 x 177 değerine ulaşır. Bu ilişki şu şekilde ifade edilebilir:
kenar uzunluğu = 17 + 4 x sürümModel 2 toplam 40 sürüm ile sayısal, alfasayısal, bayt ve Kanji veri kiplerini destekler.
Kaynak kod, mimari olarak ISO standardını doğrudan gerçekleyen kompakt kodlayıcılar ailesinde yer alır. Veri kipinin seçilmesi, en küçük uygun sürümün aranması, hata düzeltme bloklarının oluşturulması, bütün maskelerin puanlanması ve en uygun maskenin seçilmesi gibi adımlar Project Nayuki'nin standart odaklı referans uygulamasında da aynı genel sırayla bulunur. Ben bu yaklaşımı C# tabanlı web altyapıma, doğrudan görüntü üretimine ve kısa URL kullanımına göre yeniden gerçekledim.
Kütüphane genel amaçlı bir barkod paketi değildir. Kod çözme, kamera görüntüsünden sembol bulma, Micro QR, rMQR veya çok sembollü structured append işlevleri içermez. Amacı, sınırlı uzunluktaki URL ve metinleri düşük gecikmeyle standart bir QR matrisine dönüştürmektir. Bu kapsam daraltması, canlı web kullanımındaki başarımın önemli nedenlerinden biridir.
Veri kipinin seçilmesi
QR Code, her karakteri aynı sayıda bitle kodlamak zorunda değildir. Yalnız rakamlardan oluşan bir veri, sayısal kipte daha yoğun biçimde saklanabilir. Belirli büyük harfler, rakamlar ve sınırlı noktalama işaretlerinden oluşan veri alfasayısal kipte kodlanabilir. Diğer metinler bayt kipine geçirilir.
Kütüphane girişin tamamını önce sayısal, ardından alfasayısal kip açısından sınar. Bu koşullar sağlanmıyorsa metni UTF-8 baytlarına dönüştürür. Sayısal kipte üç rakam 10 bit içinde, alfasayısal kipte iki karakter 11 bit içinde saklanır. URL içinde küçük harfler bulunduğu için kişisel web sitemdeki adreslerin çoğu doğal olarak bayt kipine geçer.
Bu yaklaşım tek parçalı kip seçimi yapar. Aynı metin içinde sayısal, alfasayısal ve bayt kipleri arasında en uygun geçişleri arayan dinamik programlama bulunmaz. Kısa URL değerlerinde böyle bir optimizasyonun sağlayacağı kapasite kazancı, getireceği kod ve çalışma zamanı karmaşıklığından daha az önemlidir.
Kodda Kanji ve ECI kiplerine ilişkin temel tanımlar bulunmasına rağmen yüksek seviyeli metin yolu bunları etkin biçimde kullanmaz. Türkçe URL'ler UTF-8 bayt kipinde güvenilir biçimde kodlanır. Bu, web adresleri için uygun ve öngörülebilir bir tercihtir.
Sürüm ve hata düzeltme seçimi
Kütüphane önce veriyi taşıyabilecek en küçük sürümü bulur. Benim kullanımımda alt sınır sürüm 3 olarak belirlenmiştir. Sürüm 3, 29 x 29 modüllük bir matris üretir. Çok kısa bir URL daha küçük bir sürüme sığabilecek olsa bile bu alt sınır, web sayfalarında ve belgelerde daha tutarlı bir görsel boyut sağlar.
Daha önemli optimizasyon hata düzeltme düzeyinin seçilmesidir. Algoritma başlangıçta düşük seviyeyi kabul eder, uygun sürüm bulunduktan sonra sembolü büyütmeden kullanılabilecek en yüksek hata düzeltme seviyesine geçer. Böylece aynı matris boyutu içinde daha dayanıklı bir QR kod elde edilir.
QR Code dört hata düzeltme seviyesi tanımlar:
- L, yaklaşık yüzde 7
- M, yaklaşık yüzde 15
- Q, yaklaşık yüzde 25
- H, yaklaşık yüzde 30
Bu oranlar, toplam kod sözcükleri içindeki yaklaşık geri kazanım kapasitesini ifade eder. Hata düzeltme gücü arttıkça veri kapasitesi azalır. Bu nedenle yüksek seviye her durumda en iyi seçim değildir. Denso Wave temiz ortamlarda L seviyesinin, kirlenme veya hasar riski bulunan ortamlarda Q ya da H seviyesinin kullanılabileceğini belirtir. Hata düzeltme Reed-Solomon kodlarıyla sağlanır.
Sürümü sabit tutup kapasite izin verdiği ölçüde hata düzeltmeyi yükseltmek, özellikle kısa URL'lerde iyi bir mühendislik kararıdır. Sembol büyümez, üretim maliyeti anlamlı ölçüde artmaz ve kamera okuması daha dayanıklı hale gelir.
Reed-Solomon kodlarının üretilmesi
Veri biti dizisine kip bilgisi ve karakter sayısı eklendikten sonra bit akışı sonlandırılır, bayt sınırına tamamlanır ve gerekli kapasiteye ulaşana kadar standart dolgu baytları kullanılır. Ardından veri, sürüm ve hata düzeltme tablosunun belirlediği bloklara ayrılır.
Her blok için Reed-Solomon hata düzeltme kodları "GF(2^8)" sonlu alanında hesaplanır. Kütüphane alan çarpımını hazır logaritma ve üs tabloları yerine bit düzeyindeki polinom aritmetiğiyle gerçekleştirir. Kullanılan indirgeme polinomu "0x11D" değeridir. Üreteç polinomu gerekli hata düzeltme uzunluğuna göre çalışma anında oluşturulur.
Bu tercih genel amaçlı en hızlı Reed-Solomon gerçeklenimi olmak zorunda değildir. Ancak URL sınırları altında bloklar küçük, hata düzeltme dereceleri sınırlı ve toplam veri miktarı düşüktür. Büyük yardımcı tablolar yerine kısa ve deterministik bir hesaplama kullanmak, kütüphanenin kendi kendine yeterli kalmasını sağlar.
Veri ve hata düzeltme sözcükleri bloklar arasında serpiştirilir. Bu işlem, sembolün belirli bir bölgesindeki fiziksel hasarın yalnız tek bir Reed-Solomon bloğunu yok etmesini önlemeye yardımcı olur. Sonuçta elde edilen bit akışı, matrisin sağ alt bölümünden başlayarak ikişer sütun halinde zikzak düzeninde yerleştirilir.
İşlev desenlerinin oluşturulması
QR matrisinin bütün hücreleri veri taşımaz. Kodlayıcı önce tarayıcının sembolü tanıması ve yorumlaması için gereken sabit yapıları yerleştirir:
- Üç konum belirleme deseni
- Yatay ve dikey zamanlama desenleri
- Sürüme bağlı hizalama desenleri
- Hata düzeltme ve maske bilgisini taşıyan format bitleri
- Yüksek sürümlerde sürüm bilgisi
- Sabit koyu modül
Kütüphane veri modülleriyle işlev modüllerini iki ayrı düz dizide takip eder. İki boyutlu dizi veya piksel nesnesi yerine tek boyutlu "bool" diziler kullanılması, indis hesabını basitleştirir ve matris taramalarında düzenli bellek erişimi sağlar.
Bu ayrım maskeleme sırasında önemlidir. Maske yalnız veri ve hata düzeltme modüllerine uygulanır. Konum, zamanlama, hizalama ve format desenleri değişmeden kalır.
Sekiz maskenin değerlendirilmesi
QR matrisindeki ham veri bitleri doğrudan bırakılırsa uzun siyah veya beyaz diziler, geniş tek renkli alanlar ve konum belirleme desenine benzeyen rastlantısal şekiller oluşabilir. Bunlar optik okumayı zorlaştırır. QR standardı bu nedenle sekiz ayrı maske formülü tanımlar.
Kütüphane sekiz maskeyi de sırayla uygular ve her sonuç için ceza puanı hesaplar. Değerlendirme dört temel soruna bakar:
- Aynı renkte uzun yatay ve dikey diziler
- Tek renkten oluşan 2 x 2 bloklar
- Konum belirleme desenine benzeyen oranlar
- Siyah ve beyaz modüllerin dengesizliği
Ceza katsayıları standarttaki "3", "3", "40" ve "10" değerleriyle uygulanır. En düşük toplam puanı üreten maske son sembolde bırakılır. Bu bölüm, basit bir QR üretici ile üretim kalitesini dikkate alan bir kodlayıcı arasındaki önemli farklardan biridir.
Maske seçimi için sekiz matrisin ayrı ayrı tahsis edilmemesi de bilinçli bir optimizasyondur. Aynı modül dizisi üzerinde maske uygulanır, puanlanır ve geri alınır. Yalnız en iyi maskenin numarası saklanır.
Kaynak nüshasını yeniden değerlendirirken 5, 6 ve 7 numaralı maske ifadelerinin C# operatör önceliğinden bağımsız olacak şekilde açık parantezlerle yazılması ve standart test vektörleriyle doğrulanması gerekir. QR kodlayıcılarında maske formülü ile format alanında bildirilen maske numarasının birebir uyuşması, farklı okuyucularla birlikte çalışabilirlik için zorunludur.
Neden milisaniye düzeyinde çalışıyor
Genel bir QR kodlayıcının maliyetini giriş uzunluğu "n", matris kenarı "S" ve kod sözcüğü sayısı "C" üzerinden değerlendirebiliriz.
Veri kipi seçimi ve bit dizisinin kurulması:
Theta(n)Reed-Solomon üretimi kullanılan hata düzeltme uzunluğuna bağlı olarak yaklaşık:
O(C x E)Matris kurulumu, veri yerleşimi, maskeleme ve görüntü üretimi:
Theta(S²)Sekiz maske ayrı ayrı değerlendirildiği için sabit katsayı büyür, fakat asimptotik yapı değişmez:
Theta(8 x S²) = Theta(S²)Bellek maliyeti esas olarak modül ve işlev dizilerinden gelir:
Theta(S² + C)Benim web kullanımımda giriş 60 baytla sınırlandırılmıştır. Sürüm alt sınırı 3 olsa da URL'ler genellikle küçük sürümlerde kalır. Bu nedenle algoritma, teorik olarak değişken boyutlu olmasına rağmen canlı sistemde dar ve önceden bilinen bir çalışma aralığında yürür.
Dış süreç başlatılmaz, ağ servisine çağrı yapılmaz, veri tabanı sorgulanmaz ve üçüncü taraf QR hizmeti kullanılmaz. Kosinüs, görüntü analizi veya yinelemeli optimizasyon gibi ağır işlemler de bulunmaz. İş yükü küçük bit dizileri, sonlu alan işlemleri ve birkaç bin matris hücresinden oluşur.
Görüntü aşamasında yalnız koyu modüller dikdörtgen olarak çizilir. Ölçek sabittir ve görüntü boyutu küçüktür. Bu nedenle GDI+ üzerinden bitmap oluşturma maliyeti bile normal web isteği içinde düşük kalır. Yıllar boyunca gözlemlediğim milisaniye düzeyindeki üretim süresi bu sınırlı ve deterministik tasarımın sonucudur.
Aynı URL sık isteniyorsa HTTP önbellekleme, ETag veya uygulama içi küçük bir sonuç önbelleği eklenebilir. Böylece ilk istekte dinamik oluşturulan içerik sonraki isteklerde gerçek anlamda statik dosyaya yakın bir yoldan sunulabilir. Ancak benim kullanımımda ham üretim maliyeti yeterince düşük olduğu için dinamik oluşturma tek başına da sorun oluşturmadı.
Kişisel web sitesindeki kullanımım
Her içerik sayfası için ayrı bir QR dosyası oluşturmak ilk bakışta daha hızlı görünebilir. Gerçekte bu yaklaşım dosya yaşam döngüsü problemi üretir. Yeni sayfa eklendiğinde yeni görsel oluşturulmalı, URL değiştiğinde dosya yenilenmeli ve eski varlıklar temizlenmelidir.
Dinamik üretimde kaynak doğrudan mevcut URL'dir. QR görüntüsü istek anında oluşturulur ve sayfaya eklenir. Böylece içerik yönlendirmeleriyle QR varlıkları arasında ayrı bir eşleme tablosu bulunmaz.
Bu modelde QR kodun kendisi dinamik bir yönlendirme hizmeti değildir. Matrisin taşıdığı URL sabittir. Dinamik olan, görüntünün sunucu tarafında çalışma anında üretilmesidir. Bu ayrım önemlidir. Üçüncü taraf bir dinamik QR sağlayıcısına, izleme bağlantısına veya dış yönlendirme servisine ihtiyaç duyulmaz. Alan adı ve erişim kayıtları tamamen benim denetimimde kalır.
Özgeçmişte kullandığım QR kod da basılı belge ile güncel dijital profil arasında bir köprü kurdu. Belgenin içine bütün proje ayrıntılarını sığdırmak yerine okuyucuyu güncel web sayfasına yönlendirebildim. Buradaki kalıcılık QR koddan değil, kendi alan adımı ve URL yapımı uzun süre korumamdan gelir.
Menü kullanımındaki gerçek fayda
Restoran ve kafelerde QR menünün başarısı, yalnız basılı menüyü telefona taşımaktan kaynaklanmaz. Asıl değer içerik ile fiziksel taşıyıcının birbirinden ayrılmasıdır.
Masadaki QR kod aynı kalırken şu bilgiler merkezi olarak güncellenebilir:
- Fiyatlar
- Ürün açıklamaları
- Alerjen bilgileri
- Mevcut olmayan ürünler
- Günlük menüler
- Farklı dil seçenekleri
- Kampanyalar
Bu yapı baskı maliyetini ve eski bilgi sunma riskini azaltır. Ancak iyi bir QR menü deneyimi için hedef sayfanın hızlı açılması, mobil ekrana uygun olması ve kullanıcının uygulama yüklemesini gerektirmemesi gerekir. Menü sayfası QR koddan daha yavaş veya daha karmaşıksa, iyi üretilmiş bir sembol tek başına başarılı bir deneyim oluşturmaz.
Kısa ve doğrudan URL kullanmak burada özellikle önemlidir. URL uzadıkça daha yüksek sürüm gerekir, modüller küçülür ve aynı fiziksel alanda okuma zorlaşır. Gereksiz takip parametreleri ve uzun yönlendirme zincirleri yerine işletmenin kendi alan adındaki kararlı bir adres tercih edilmelidir.
Baskı ve sunum sınırları
Kaynak kodda iç kenar boşluğu bir modül olarak belirlenmiştir. Denso Wave, standart QR Code çevresinde dört modüllük boş bir quiet zone bulunmasını ister. Web sayfasındaki beyaz alan veya belgedeki görsel çerçevesi fiilen ek boşluk sağlayabilir ve benim kullanımımda okuma başarılı olabilir. Bununla birlikte bağımsız olarak dağıtılan PNG, PDF veya baskı çıktısında dört modüllük boşluk doğrudan görüntünün içinde güvence altına alınmalıdır.
Görüntüde modül ölçeği üç piksel olarak kullanılmıştır. Ekran sunumunda bu değer çoğu durumda yeterlidir. Baskıda ise fiziksel modül boyutu, yazıcı çözünürlüğü ve tarama mesafesi birlikte değerlendirilmelidir. Denso Wave, kararlı baskı için bir modülün en az dört yazıcı noktasıyla oluşturulmasını önerir.
Koyu modüllerde siyah yerine koyu lacivert kullanıyorum. QR Code mutlak olarak siyah renk gerektirmez, ancak açık ve koyu modüller arasında güçlü kontrast bulunmalıdır. Şeffaf arka planlı görüntü beyaz bir sayfada sorunsuz çalışırken renkli veya desenli bir zemin üzerinde kontrastı kaybedebilir. Bu nedenle web tarafında QR alanının beyaz arka planı ayrıca güvenceye alınmalıdır.
PNG, keskin modül kenarlarını kayıpsız koruduğu için QR kod sunumunda JPEG'den daha uygundur. JPEG kodlama küçük blokların kenarlarında bulanıklık ve halka artefaktları oluşturabilir. Kütüphane JPEG çıktısında arka planı beyaza çevirse de normal kullanımda PNG daha doğru seçimdir.
Bir başka kullanım sözleşmesi, 60 baytlık veri sınırıdır. Mevcut gerçeklenim uzun girdiyi kırpar. URL üretiminde bu durum sessizce farklı veya geçersiz bir adrese yol açabileceği için çağıran katman uzunluğu önceden doğrulamalıdır. Genel amaçlı bir sürümde kırpma yerine açık hata üretmek daha güvenlidir.
Algoritmanın değeri
Bu kütüphanenin değeri, yeni bir QR sembolojisi icat etmesinden gelmiyor. Değeri, iyi tanımlanmış bir uluslararası standardı kendi yazılım mimarime uygun, küçük, hızlı ve bağımsız bir bileşen olarak gerçeklememden geliyor.
Uygulama şu özellikleri bir araya getiriyor:
- Veriye göre sayısal, alfasayısal veya bayt kipi seçimi
- En küçük uygun sürümün bulunması
- Sembol büyümeden hata düzeltmenin yükseltilmesi
- Reed-Solomon kodlarının yerel olarak üretilmesi
- İşlev desenlerinin doğrudan matrise yazılması
- Sekiz maskenin tamamının puanlanması
- Tek boyutlu ve düzenli bellek yerleşimi
- Harici servis veya üçüncü taraf bağımlılığı olmadan görüntü üretimi
- URL odaklı sınırlı çalışma alanı
Bu nedenle algoritmayı, genel amaçlı QR paketleriyle basit bir hız yarışında konumlandırmıyorum. Daha doğru tanım, kurumsal nitelikteki tam bir Model 2 kodlayıcının web sitesi için özelleştirilmiş, sınırları belirlenmiş bir gerçeklenimidir.
Yıllardır kişisel web sitemde kullanmam, özgeçmişlerimde pratik faydasını görmem ve farklı cihazlarla sorunsuz okutabilmem, geliştirme kararlarının gerçek kullanımda karşılık bulduğunu gösterdi. Statik dosyaya yakın sunum süresi de tek bir mikro optimizasyondan değil, problemin doğru sınırlandırılmasından doğdu.
QR Code'un başarısı da benzer bir mühendislik anlayışına dayanır. Konum belirleme deseni hızlı okumayı, Reed-Solomon kodları hasar toleransını, kipler veri yoğunluğunu ve maskeler optik kararlılığı sağlar. Benim kütüphanem bu katmanları eksiltmeden, kısa URL üretiminin gerektirdiği kadar küçük ve hızlı bir çalışma hattında birleştirir.