【Ruby】JANCODE-nicotan / JANCODE-nicBAR 用の文字列を返します

Rubyファイルのダウンロードはこちら

※ご利用に関して
MIT ライセンス
Copyright (c) 2014 nicotan
Released under the MIT license
http://opensource.org/licenses/mit-license.php

MIT ライセンスの全文の意訳の引用元
http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license#h1-The.20MIT.20License

The MIT License

Copyright (c) year copyright holders
以下に定める条件に従い、本ソフトウェアおよび関連文書のファイル(以下「ソフトウェア」)の複製を取得するすべての人に対し、ソフトウェアを無制限に扱うことを無償で許可します。

これには、ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、サブライセンス、および/または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます。

上記の著作権表示および本許諾表示を、ソフトウェアのすべての複製または重要な部分に記載するものとします。
ソフトウェアは「現状のまま」で、明示であるか暗黙であるかを問わず、何らの保証もなく提供されます。
ここでいう保証とは、商品性、特定の目的への適合性、および権利非侵害についての保証も含みますが、それに限定されるものではありません。
作者または著作権者は、契約行為、不法行為、またはそれ以外であろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの使用またはその他の扱いによって生じる一切の請求、損害、その他の義務について何らの責任も負わないものとします。
つまり Copyright ~の3行を使用箇所に書いてもらえればなにしても自由。ただ何かあっても責任は負わないです。

Ruby関数バージョン

ダウンロード:無料。def_jan.rb 右クリックして対象をファイルに保存を選んでね。
バージョン:(2014.12.17)
★ jan() 引数に文字列数値、数値、配列を入れると、バーコードのフォント用文字列が返ります。
  • 7桁の数値
  • 8桁の数値
  • 12桁の数値
  • 13桁の数値
  • 上記4種類の文字列の数値
  • 13桁の半角ハイフン(-)付きの文字列
  • 上記が入っている配列
を入れるとフォント用の文字列を返します。
※画像は、def_jan.rb を実行すると7桁のJAN(数値)~・・・と表示されていますが、参考までに出力したもので実際には表示されません。

require "./def_jan"
print jan("490210207261")
=> "X9A21ACKLSNRMTZ"

print jan([["49122145","490210207261"],["4901681502516"]])
=> [["Y4912KNMPQZ","X9A21ACKLSNRMTZ"],["X9A161BKQLNQMRZ"]]
cmd_ruby_def_jan

Ruby Classバージョン

ダウンロード:無料。jan.rb 右クリックして対象をファイルに保存を選んでね。
バージョン:(2015.3.31)
★ Class Jan < Hash ハッシュを継承しています
★ Jan.new(option) でインスタンスを作成します(optionは省略可。作成後にメソッドでいじれる・・・予定)
★ 引数にはオプションとして Hash で与えます。初期値に置換するための文字列 hash={rep:"-"} が指定されていてます。Hash のキーに 『:rep』(シンボル)、値に『文字列』or『文字列の配列』を与えるとJANコードが置換されます。
★ Hash 同様 [] を使用します。[KEY] KEY にJANコードを入れると、自動的にJANコードをシンボル化し、値にはフォント用の文字列がセットされます
★ KEY に配列を入れた場合は flatten(平坦化) した上で、JANコードのみを KEY.to_sym => VALUE でセットされます。違う場合は nil を返し、セットしません。最終的に配列で返します。入れたときの配列の形は復元されません(flatten)
★ KEY にJANコード以外を入れた場合は nil が返ります(はず)。KEYとVALUEにはセットされません(たぶん)
★ KEY に Hash を入れた場合は未作成です nil が返ります。でも Key のみ value のみとかどっちもとか 新しく Hash で返すとかいろいろできそう
★ KEY に シンボル化したJANコードを入れると計算をせず、登録されている文字列が返ります。存在しない場合は通常通り nil が返ります
★ メソッド .replace(obj)
obj には置換用の『文字列』『配列』『Hash』を入れてください。初期値の"-"に加えられます。Hashの場合は KEY に :rep として値(文字列、文字列の配列)を入れてください。
★ メソッド .options
クラス作成時に引数に入れた Hash を返します。追記していた場合も出ます
★ (一応、.jan()のメイン、.jancd()のチェックデジット、もあります。)
★ Hash の各種メソッドが利用できます(未検証)
★ .each では :"JANコード", "文字列" が取り出せます
※ [] をいじったので、通常の Hash で出来ることができなくなっている場合があるかもしれません
※ def_jan.rb の関数を一部改良してクラス化しています
cmd_ruby_class_jan

ファイル名:def_jan.rb ソースコード (2014.12.17)

Initial = ["000000","001011","001101","001110","010011","011001","011100","010101","010110","011010"]
StartCode = ["a","b","W","d","X","f","g","h","i","j"]
Bar = [
["0","1","2","3","4","5","6","7","8","9"],
["A","B","C","D","E","F","G","H","I","J"],
["L","M","N","O","P","Q","R","S","T","U"]
]

def jan(obj=nil)
case
when obj.instance_of?(String)
obj = janicorep(obj)
if isNumeric?(obj)
s = obj.size
case s
when 7,8
return seven(obj)
when 12,13
return twelve(obj)
else
return nil
end
else
return nil
end
when obj.instance_of?(Array)
a = Array.new
obj.each {|tmp|
a << jan(tmp)
}
return a
when obj.instance_of?(Bignum)
return jan(obj.to_s)
when obj.instance_of?(Fixnum)
return jan(obj.to_s)
else
return nil
end
end
jan() 引数には文字列、数字、配列を入れてください。
いろんなクラスを入れてみた結果、when 以外のクラスや、
JANコード以外は nil が返ってきます(来るはず)
case 文で各クラスごとに分けて処理します
頭が0で始まるパターンもあるので文字列数字が好ましいです。
janicorep() はハイフンが含まれる場合は削除します。

isNumeric?()は文字列の数字なのかどうか判定します。

文字数(数字の桁)によって分岐します。

配列の場合は、配列の中身を1つずつ取り出し、
取り出したものを jan() で処理します。(再起)
同じ状態にするため仮の配列を作り、
入れなおし返すという形で元に戻します

数値は文字列にした上で jan() で処理します。(再起)

def isNumeric?(str)
Integer(str)
true
rescue
false
end
isNumeric? は引数の文字列を Integer で変換した際、
問題なく数値にできれば文字列の数値である
それ以外はエラーが発生するので rescue が拾って false を返す
文字列の小数点もエラーが出る。
数値の小数点は、その前の分岐のクラス分けで else で return nil される
Ruby にも公式の isNumeric? ほしいよね


def janicorep(obj)
return obj.gsub("-","")
end
変な名前なのは rep だと他で作られたものとかぶりそうだったのでw
jan() の文字列引数をもう1個作って、
その文字列を消すみたいにしたらおもしろそう
たとえば jan( testjan , "-") とか




def seven(n)
strJan = "Y"
4.times {|i|
strJan << Bar[0][n[i].to_i]
}
strJan << "K"
for i in 4..6
strJan << Bar[2][n[i].to_i]
end
strJan << Bar[2][jancd(n)]
strJan << "Z"
return strJan
end
短縮JANの変換
スタートコードは Y
左側4つは Bar 配列の0個目の配列を使用
文字列なので [] を使用して i 番目の文字列を取り出す
取り出した文字列数値を.to_i(数値)にし、配列の index で取り出す
と思ったがそのまま数字入れればいいじゃん!!!!(n[i])
センターコードは K
右側4つは Bar 配列の2個目の配列を使用
4つ目は jancd() でチェックデジットを入れる
エンドコードは Z

def twelve(n)
strJan = ""
strJan << StartCode[n[0].to_i]
6.times {|i| strJan << Bar[Initial[n[0].to_i][i].to_i][n[i+1].to_i] }
strJan << "K"
for i in 7..11
strJan << Bar[2][n[i].to_i]
end
strJan << Bar[2][jancd(n)]
strJan << "Z"
return strJan
end
文字列なので 1文字目は n[0]
左側の部分は6.timesの1行
[] 多すぎてややこしい
まずBar[][]の形
Bar[]には0か1か
それはJANの先頭の文字で決まる
Initial[ n[0].to_i ] => 010011
010011を1個ずつ取り出すので
6.times の Initial[][i]
でBar[][]の2つ目は
JANの先頭の文字の次から
6.times の i は 0 スタートなので+1
6文字分繰り返し、文字列数値を
数値にして index にする
右側は短縮と同様。







def jancd(n)
s,m,g,k,h = n.size,"",0,0,0
case s
when 7,8
m = ("00000" + n.to_s)[0..11]
when 12,13
m = n.to_s[0..11]
else
return nil
end
-1.step(-12,-2) {|i|
g += m[i].to_i
k += m[i-1].to_i
}
h = (g * 3 + k).to_s[-1].to_i
return h == 0 ? 0 : 10 - h
end
変数の用意
複数作成し、同じ分だけ値を用意
文字数(桁数)によって分ける
7桁8桁に00000を付ける
8桁では1個多いように見えるが[0..11]によって
0~11文字、つまり1~12文字目までを m に代入
13桁あっても同じように12文字に削る
奇数、偶数で2回for文必要かと思ったけど
1回のfor文(step)で済むことに気づいた
-1から-2ずつ足して-12になるまで続ける
文字列[-1]は一番右側(末尾)の文字の意味
"teststr"[-1]は"r"
.to_s[-1].to_i 文字列にして1桁目とって数字に戻す
== ? : は if と同じ

ファイル名:jan.rb ソースコード (2015.3.31)

				
class Jan < Hash
  def initialize(option={rep:"-"})
    @Initial = ["000000","001011","001101","001110","010011","011001","011100","010101","010110","011010"]
    @StartCode = ["a","b","W","d","X","f","g","h","i","j"]
    @Bar = [["0","1","2","3","4","5","6","7","8","9"],["A","B","C","D","E","F","G","H","I","J"],["L","M","N","O","P","Q","R","S","T","U"]]
    @option = option
  end

  def [](key=nil)
    case
      when key.instance_of?(Symbol)
        super(key)
      when key.instance_of?(String), key.instance_of?(Bignum), key.instance_of?(Fixnum)
        stmp = jan(key)
        if stmp
          self[key.to_s.to_sym] = stmp
        end
      when key.instance_of?(Array)
        atmp = Array.new
        key.flatten.each {|k|
          ktmp = jan(k)
          if ktmp
            self[k.to_s.to_sym] = ktmp
            atmp << ktmp
          else
            atmp << nil
          end
        }
        return atmp
#      when key.instance_of?(Hash)
#        return nil
      else
        return nil
    end
  end

  def jan(obj=nil)
    case
      when obj.instance_of?(String)
        obj = rep(obj)
        if numeric?(obj)
          s = obj.size
          case s
            when 7,8
              return seven(obj)
            when 12,13
              return twelve(obj)
            else
              return nil
          end
        else
          return nil
        end
      when obj.instance_of?(Bignum)
        return jan(obj.to_s)
      when obj.instance_of?(Fixnum)
        return jan(obj.to_s)
      when obj.instance_of?(Array)
        a = Array.new
        obj.each {|tmp|
          a << jan(tmp)
        }
        return a
      else
        return nil
    end
  end

  def numeric?(str)
    Integer(str)
    true
  rescue
    false
  end

  def rep(obj)
    rtmp = @option[:rep]
    if rtmp.instance_of?(String)
      return obj.gsub!(rtmp, "") || obj
    elsif rtmp.instance_of?(Array)
      tmpobj = ""
      rtmp.each {|v|
        tmpobj = obj.gsub!(v, "") || obj
      }
      return tmpobj
    else
      return obj
    end
  end

  def seven(n)
    strJan = ""
    strJan = "Y"
    4.times {|i| strJan << n[i] }
    strJan << "K"
    for i in 4..6
      strJan << @Bar[2][n[i].to_i]
    end
    strJan << @Bar[2][jancd(n)]
    strJan << "Z"
    return strJan
  end

  def twelve(n)
    strJan = ""
    strJan << @StartCode[n[0].to_i]
    6.times {|i| strJan << @Bar[@Initial[n[0].to_i][i].to_i][n[i+1].to_i] }
    strJan << "K"
    for i in 7..11
      strJan << @Bar[2][n[i].to_i]
    end
    strJan << @Bar[2][jancd(n)]
    strJan << "Z"
    return strJan
  end

  def jancd(n)
    s,m,g,k,h = n.size,"",0,0,0
    case s
      when 7,8
        m = ("00000" + n.to_s)[0..11]
      when 12,13
        m = n.to_s[0..11]
      else
        return nil
    end
    -1.step(-12,-2) {|i|
      g += m[i].to_i
      k += m[i-1].to_i
    }
    h = (g * 3 + k).to_s[-1].to_i
    return h == 0 ? 0 : 10 - h
  end

  def options
    return @option
  end

  def replace(obj=nil)
    case
      when obj.instance_of?(String)
        add_replace(obj)
        return @option
      when obj.instance_of?(Array)
        obj.each {|v|
          add_replace(v)
        }
        return @option
      when obj.instance_of?(Hash)
        tmp = obj[:rep]
        if tmp
          replace(tmp)
        end
        return @option
      else
        return "nil"
    end
  end

  def add_replace(obj)
    if @option[:rep].instance_of?(String)
      a = Array.new
      tmp = @option[:rep]
      a << tmp
      a << obj
      @option[:rep] = a
    else
      @option[:rep] << obj
    end
    @option[:rep].uniq!
  end
  private :add_replace
end
				
				



わかんなかったら連絡ちょうだいね
また、エクセルでこんなのほしいとかあったら言ってね
プロじゃないのでできないものはできませんができるものはできるとおもいます。
少しでも業務多忙のみなさんの時間短縮になれば幸いです
jancode.nicotan@gmail.com
(*´Д`*)v