[RAILS] [Ruby] Generiere verketteten QR-Code mit rqrcode (Übung)

Ändern Sie den rqrcode

Über die Bibliotheksstruktur von rqrcode

Fügen Sie eine Methode hinzu, um den Header-Teil des verketteten QR-Codes zu schreiben

rqrcode_core/qrcode/qr_bit_buffer.rb


module RQRCodeCore
  class QRBitBuffer
    #Unterlassung
    def byte_with_connected_encoding_start(length, page_number, last_page_number, parity)
      put(3, 4) #MODE, der den verketteten QR-Code anzeigt= 0b0011
      put(page_number, 4) #Sequenznummer(0〜15)
      put(last_page_number, 4) #Letzte Sequenznummer(0〜15)
      put(parity, 8) #Paritätswert(XOR-Wert aller Daten)
      put(QRMODE[:mode_8bit_byte], 4) # 8bit_Byte-Modus-Wert
      put(length, QRUtil.get_length_in_bits(QRMODE[:mode_8bit_byte], @version)) #Datenlänge
    end

Erstellen Sie eine Klasse für verketteten QR-Code

rqrcode_core/qrcode/qr_8bit_byte_with_connected.rb


# frozen_string_literal: true

module RQRCodeCore
  class QR8BitByteWithConnected
    attr_reader :mode, :page_number, :last_page_number, :parity

    def initialize(data, page_number, last_page_number, parity)
      @mode = QRMODE[:mode_8bit_byte]
      @data = data
      @page_number = page_number
      @last_page_number = last_page_number
      @parity = parity
    end

    def get_length
      @data.bytesize
    end

    def write(buffer)
      buffer.byte_with_connected_encoding_start(get_length, @page_number, @last_page_number, @parity)
      @data.each_byte do |b|
        buffer.put(b, 8)
      end
    end
  end
end

Fügen Sie der QRCode-Klasse eine verkettete QR-Code-Option hinzu

rqrcode_core/qrcode/qr_code.rb


module RQRCodeCore
  #Unterlassung
  class QRCode
    attr_reader :modules, :module_count, :version
    #Unterlassung
    def initialize( string, *args )
      if !string.is_a? String
        raise QRCodeArgumentError, "The passed data is #{string.class}, not String"
      end

      options               = extract_options!(args)
      level                 = (options[:level] || :h).to_sym
      #Optionsbeurteilung für verketteten QR-Code hinzugefügt
      with_connected = options[:connected] || false

      #Unterlassung

      # :byte_Fehler, wenn ein anderer verketteter QR-Code als 8 Bit angegeben wird(Die Implementierung ist optional)
      if with_connected && mode != QRMODE_NAME[:byte_8bit]
        raise QRCodeArgumentError, 'Argument error.(Connected QRCode is byte_8bit mode only)'
      end

      max_size_array        = QRMAXDIGITS[level][mode]
      size                  = options[:size] || smallest_size_for(string, max_size_array)

      if size > QRUtil.max_size
        raise QRCodeArgumentError, "Given size greater than maximum possible size of #{QRUtil.max_size}"
      end

      #Unterlassung
      @data_list =
        case mode
        when :mode_number
          QRNumeric.new( @data )
        when :mode_alpha_numk
          QRAlphanumeric.new( @data )
        else
          #Wenn es sich um einen verketteten QR-Code handelt, ändern Sie die generierte Klasse
          if with_connected
            page_number = options[:page_number]
            last_page_number = options[:last_page_number]
            parity = options[:parity]
            QR8BitByteWithConnected.new(@data, page_number, last_page_number, parity)
          else
            QR8bitByte.new(@data)
          end
        end

      @data_cache           = nil
      self.make
    end

Verketteten QR-Code ausgeben

JAHIS7
1,1,1234567,13,Kita Klinik für Innere Medizin
2,999-9999,99-999 Testgebäude 9F, Kita Shinagawa, Shinagawa-ku, Tokio
3,03-9999-9991,03-9999-9992,
4,1,,Innere Medizin
5,,,Arzt Taro
11,,Patient Hanako,Kanja Hanako
12,2
13,20000103
21,1
22,01010016
23,Symbol,Nummer,2,
51,20200818
81,1,,
81,2,,Dies ist eine Bemerkungsspalte für Rezepte.
101,1,3,,1
111,1,1,,An den Beinen,
201,1,1,1,7,2619803XAZZZ,[Allgemein] Externe alkoholhaltige Lösung zur Desinfektion,4,1,mL
101,2,1,,5
111,2,1,,Einmal am Tag nach dem Abendessen,
201,2,1,1,7,1124022F2ZZZ,[Allgemein] Lorazepam Tabletten 1 mg,1,1,Sperren
101,3,1,,28
111,3,1,,3 mal am Tag nach jeder Mahlzeit,
201,3,1,1,7,3136004F2ZZZ,[Allgemein] Mecobalamin-Tabletten 0,5 mg,3,1,Sperren
201,3,2,1,7,2171017F2ZZZ,[Allgemein] Nicolanzil Tabletten 5 mg,3,1,Sperren
201,3,3,1,7,3962001F1ZZZ,[Allgemein] Buforminhydrochlorid-Tabletten 50 mg,3,1,Sperren
201,3,4,1,7,1124022F1ZZZ,[Allgemein] Lorazepam Tabletten 0,5 mg,3,1,Sperren
201,3,5,1,7,1124026F1ZZZ,[Allgemein] Tophisopam-Tabletten 50 mg,3,1,Sperren
201,3,6,1,2,612140503,,3,1,Sperren
101,4,1,,28
111,4,1,,3 mal am Tag nach jeder Mahlzeit,
201,4,1,1,7,2344009F2ZZZ,[Allgemein] Magnesiumoxidtablette 330 mg,6,1,Sperren
101,5,3,,1
111,5,1,,An den Beinen,
201,5,1,1,7,2619803XAZZZ,[Allgemein] Externe alkoholhaltige Lösung zur Desinfektion,4,1,mL
101,6,1,,28
111,6,1,,3 mal am Tag nach jeder Mahlzeit,
201,6,1,1,7,3136004F2ZZZ,[Allgemein] Mecobalamin-Tabletten 0,5 mg,3,1,Sperren
201,6,2,1,7,2171017F2ZZZ,[Allgemein] Nicolanzil Tabletten 5 mg,3,1,Sperren
201,6,3,1,7,3962001F1ZZZ,[Allgemein] Buforminhydrochlorid-Tabletten 50 mg,3,1,Sperren
201,6,4,1,7,1124022F1ZZZ,[Allgemein] Lorazepam Tabletten 0,5 mg,3,1,Sperren
201,6,5,1,7,1124026F1ZZZ,[Allgemein] Tophisopam-Tabletten 50 mg,3,1,Sperren
201,6,6,1,2,612140503,,3,1,Sperren

Methode zur Berechnung der Parität

    def create_total_text_parity(data)
      data.each_byte.inject(0) { |parity, b| parity ^ b }
    end

Methode zum Teilen von Daten

    #Fügen Sie bei Bedarf eine Anforderung für RQRCodeCore hinzu.
    LIMIT_OF_CONNECTED_QRCODE_LENGTH = 16
    CAPACITY_GAP_FOR_CONNECTED = 2

    def slice_data_for_connected_qrcode(data, options)
      capacity = binary_qrcode_capacity_from(options[:level], options[:size]) - CAPACITY_GAP_FOR_CONNECTED

      sliced =
        if options[:adjust_for_sjis]
          slice_sjis_data(data, capacity: capacity)
        else
          slice_data(data, capacity: capacity)
        end

      fail 'data for connect QRCode too many length.' if sliced.length > LIMIT_OF_CONNECTED_QRCODE_LENGTH
      sliced
    end

    def binary_qrcode_capacity_from(level, size)
      RQRCodeCore::QRMAXDIGITS[level][:mode_8bit_byte][size - 1]
    end

    def slice_sjis_data(sjis_data, capacity:)
      is_first_char = ->(char) { (char >= 129 && char <= 159) || (char >= 224 && char <= 239) }

      bytes = sjis_data.each_byte
      sliced_list = []
      while bytes.present?
        next_bytes = bytes.take(capacity)
        if is_first_char.call(next_bytes.last) && next_bytes.length != bytes
          next_bytes = bytes.take(capacity - 1)
        end

        sliced_list << next_bytes.pack('c*')
        bytes = bytes.drop(next_bytes.length)
      end

      sliced_list
    end

    def slice_data(data, capacity:)
      data.each_byte.each_slice(capacity).map { |sliced| sliced.pack('c*') }
    end

Eine Methode, die QR-Code automatisch aufteilt und generiert

    # Generate connected QRCode. (binary mode only)
    #
    #   # data   - the string you wish to encode
    #   # args
    #   #   size   - the size of the qrcode (default 4)
    #   #   level  - the error correction level
    #   #   adjust_for_sjis - true: no split sjis multi byte character
    #
    # qrcode_list = RQRCode::ConnectedQRCodeUtil.generate_binary_connected_qrcodes('hello world', size: 1, level: :m)
    def generate_binary_connected_qrcodes(data, *args)
      options = extract_options!(args)
      #Wenn es in einen QR-Code passt, wird es mit einem normalen QR-Code generiert.
      return [RQRCode::QRCode.new(data, options)] if fits_in_single_qrcode?(data, options)

      #Daten teilen
      sliced_text = slice_data_for_connected_qrcode(data, options)
      #Parität erzeugen
      parity = create_total_text_parity(data)
      #Generieren Sie einen QR-Code basierend auf den geteilten Daten
      sliced_text.map.with_index do |text, number|
        extend_args = { page_number: number, last_page_number: sliced_text.length - 1, connected: true, parity: parity }
        RQRCode::QRCode.new(text, options.merge(extend_args))
      end
    end

    def extract_options!(arr)
      arr.last.is_a?(::Hash) ? arr.pop : {}
    end

    def fits_in_single_qrcode?(data, options)
      data.each_byte.to_a.length <= binary_qrcode_capacity_from(options[:level], options[:size])
    end

Tatsächliche Ausgabe


  QRCODE_SIZE = 16 # Size of QRCODE
  QRCODE_LEVEL = :l # Error correction level (L = 7%)
  MODULE_PIXEL_SIZE = 2 # Size of Pixel

  def create_qrcode_png_files_from(csv_data)
    qrcodes = RQRCode::ConnectedQRCodeUtil.generate_binary_connected_qrcodes(
      csv_data,
      size: QRCODE_SIZE,
      level: QRCODE_LEVEL,
      adjust_for_sjis: true
    )
    qrcodes.map.with_index do |qrcode, index|
      file_path = File.join('tmp', "qrcode_#{index}.png ")
      qrcode.as_png(module_px_size: MODULE_PIXEL_SIZE, file: file_path)
    end
  end

Zusammenfassung

Verweise

Dieser Artikel wurde unter Bezugnahme auf die folgenden Informationen verfasst.

Änderungsprotokoll

Recommended Posts

[Ruby] Generiere verketteten QR-Code mit rqrcode (Übung)
[Ruby] Generiere verketteten QR-Code mit rqrcode (Knowledge)
Formatieren Sie Ruby mit VS-Code
Lesen und generieren Sie QR-Code [Android]
Machen Sie ein Tippspiel mit Ruby
Ich habe mit Ruby einen riskanten Würfel gemacht
Extrahieren Sie einen Teil einer Zeichenfolge in Ruby
Memorandum zum Bereinigen des Codes Ruby
Erstellen eines Browser-Automatisierungstools mit Ruby + Selenium
Ich habe Code Pipeline mit AWS CDK erstellt.
[Ruby] So generieren Sie eine zufällige Alphabet-Zeichenfolge
Versuchen Sie, ein Java-Programm mit VS-Code zu debuggen
Ich habe mit Ruby On Rails ein Portfolio erstellt
Erstellen Sie eine Java-Entwicklungsumgebung mit VS Code