diff --git a/ZipConvertCustomerBarCode/BarCode.cs b/ZipConvertCustomerBarCode/BarCode.cs index 4e23d0a..08a7242 100644 --- a/ZipConvertCustomerBarCode/BarCode.cs +++ b/ZipConvertCustomerBarCode/BarCode.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; @@ -73,12 +74,12 @@ public static class BarCode /// /// 指定したパスにカスタマバーコードを出力する。 /// - /// 郵便番号 + /// 郵便番号(ハイフンなし半角数字7桁) /// 住所 /// 出力先 - public static void Export(string postcode, string zip, string outputPath) + public static void Export(string postCode, string zip, string outputPath) { - var code = ConvertCustomerBarCode(zip, postcode); + var code = ConvertCustomerBarCode(zip, CheckPostCode(postCode)); using (var img = CreateImage(code)) { img.Save(outputPath, ImageFormat.Gif); @@ -88,16 +89,39 @@ public static void Export(string postcode, string zip, string outputPath) /// /// カスタマバーコードのイメージを返す /// - /// 郵便番号 + /// 郵便番号(ハイフンなし半角数字7桁) /// 住所 /// バーコードイメージ - public static Bitmap CreateImage(string postcode, string zip) + public static Bitmap CreateImage(string postCode, string zip) { - var code = ConvertCustomerBarCode(zip, postcode); + var code = ConvertCustomerBarCode(zip, CheckPostCode(postCode)); var img = CreateImage(code); return img; } + /// + /// 郵便番号チェック + /// ハイフンを除いて数値7桁であること + /// + /// 郵便番号 + /// 郵便番号配列 + private static IEnumerable CheckPostCode(string postCode) + { + // 全角→半角 + postCode = string.Join("", postCode.Select(n => (HankakuDic.ContainsKey(n) ? HankakuDic[n] : n))); + + // ハイフン除去 + postCode = postCode.Replace("-", ""); + + if (!Regex.IsMatch(postCode, @"\A\d{7}\Z")) + { + throw new ArgumentException("郵便番号は7桁の数値で入力してください。"); + } + + return postCode.Select(x => x.ToString()); + + } + /// /// イメージ生成 /// @@ -120,20 +144,18 @@ private static Bitmap CreateImage(IEnumerable code) /// /// カスタマバーコード変換 /// - /// - /// + /// 住所 + /// 郵便番号 /// - private static IEnumerable ConvertCustomerBarCode(string zip, string postcode = null) + private static IEnumerable ConvertCustomerBarCode(string zip, IEnumerable postCode) { yield return startCode; // 全角→半角 zip = string.Join("", zip.Select(n => (HankakuDic.ContainsKey(n) ? HankakuDic[n] : n))); - foreach (var z in postcode) - { - yield return z.ToString(); - } + foreach (var pc in postCode) yield return pc; + // http://www.post.japanpost.jp/zipcode/zipmanual/p19.html // 1. まず、データ内にあるアルファベットの小文字は大文字に置き換えます。 zip = zip.ToUpper(); @@ -145,8 +167,7 @@ private static IEnumerable ConvertCustomerBarCode(string zip, string pos // 3. 1および2で整理したデータから、算用数字、ハイフンおよび連続していないアルファベット1文字を必要な文字情報として抜き出します。 // 4. 次に抜き出された文字の前にある下記の文字等は、ハイフン1文字に置き換えます。 // 「漢字」、「かな文字」、「カタカナ文字」、「漢数字」、「ブランク」、「2文字以上連続したアルファベット文字」 - var reg = new Regex("[^0-9A-Z\\-]|[A-Z]{2,}"); - zip = reg.Replace(zip, "-"); + zip = Regex.Replace(zip, "[^0-9A-Z\\-]|[A-Z]{2,}", "-"); // ハイフン処理 zip = TrimHyphen(zip); @@ -154,7 +175,7 @@ private static IEnumerable ConvertCustomerBarCode(string zip, string pos var customerCode = ConvertCCode(zip); foreach (var cd in customerCode) yield return cd; - yield return CalcCheckDigit(postcode, customerCode); + yield return CalcCheckDigit(postCode, customerCode); yield return endCode; } @@ -167,8 +188,7 @@ private static IEnumerable ConvertCustomerBarCode(string zip, string pos private static string TrimHyphen(string target) { // 5. 4の置き換えで、ハイフンが連続する場合は1つにまとめます。 - var reg = new Regex("\\-{2,}"); - target = reg.Replace(target, "-"); + target = Regex.Replace(target, "\\-{2,}", "-"); //アルファベット前後のハイフンを除去 var tmp = target.ToCharArray(); @@ -218,13 +238,13 @@ private static string[] ConvertCCode(string zip) /// /// チェックデジット計算 /// - /// 郵便番号 + /// 郵便番号 /// 住所表示番号 /// チェックデジット - private static string CalcCheckDigit(string postcode, string[] zipDisplayCode) + private static string CalcCheckDigit(IEnumerable postCode, string[] zipDisplayCode) { // 郵便番号の各値と住所表示番号の各値の合計+CD=19の倍数 - var sum = postcode.Select(x => x.ToString()).Concat(zipDisplayCode) + var sum = postCode.Concat(zipDisplayCode) .Select(x => CheckSumDic[x]).Sum(); if (sum % 19 == 0) return "0";