/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JZMFormatForMask
*   ソースファイル名：JZMFormatForMask.java
*   作成者          ：富士通
*   日付            ：2012年03月09日
*＜機能概要＞
*   マスク化部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v3.00       2012/04/24   FJ) 宮前    新規作成
*   v58.00      2022/05/30   FJ) 新谷    【ANK-3846-00-00】【クレカ】クリアパス→ペイジェント移行
*
**********************************************************************/
package eo.common.util;

import com.fujitsu.futurity.model.base.jcc.util.JCCStringChecker;

/**
 * マスク化部品のクラスです。
 * @author FJ
 *
 */
public class JZMFormatForMask 
{
	/** マスク文字 アスタリスク */
	private static final char MASK_CHAR_ASTERISK = '*';
	/** マスク文字 アスタリスク 全角 */
	private static final char MASK_ZENKAKU_CHAR_ASTERISK = '＊';
	/** マスク文字 アスタリスク 半角 固定値の場合 */
	private static final String FIXED_MASK_CHAR_ASTERISK = "***";
	/** マスク文字 アスタリスク 全角 固定値の場合 */
	private static final String FIXED_MASK_ZENKAKU_ASTERISK = "＊＊＊";
	/** マスク文字 9 */
	private static final char MASK_CHAR_9 = '9';
	/** マスク文字 9 固定値の場合 */
	private static final String FIXED_MASK_CHAR_9 = "999";
	/** パスワード用マスク文字列 */
	private static final String PASSWORD_MASK_STRING = "********";
	/** クレジットカード番号 桁数 11桁 */
	private static final int CRECARD_NO_LENGTH_11 = 11;
	/** クレジットカード番号 桁数 14桁 */
	private static final int CRECARD_NO_LENGTH_14 = 14;
	/** クレジットカード番号 桁数 15桁 */
	private static final int CRECARD_NO_LENGTH_15 = 15;
	/** クレジットカード番号 桁数 14桁 */
	private static final int CRECARD_NO_LENGTH_16 = 16;
	/** クレジットカード番号 桁数 14桁 ハイフンあり */
	private static final int CRECARD_NO_HYPHEN_14 = 16;
	/** クレジットカード番号 桁数 15桁 ハイフンあり */
	private static final int CRECARD_NO_HYPHEN_15 = 17;
	/** クレジットカード番号 桁数 16桁 ハイフンあり */
	private static final int CRECARD_NO_HYPHEN_16 = 19;
	/** マスク化除外文字 除外文字なしの場合に指定する文字 */
	private static final char NO_EXCLUDE_CHAR = ' ';
	/** クレジットカード番号 区切り文字（ハイフン） */
	private static final char CRECARD_NO_HYPHEN = '-';
	/** クレジットカード有効期限 区切り文字（スラッシュ） */
	private static final char CRECARD_KGN_SLASH = '/';
	
	/**
	 * No.1 マスク化標準処理
	 * マスク編集標準ルールに沿ったマスク化処理を行い、マスク化された文字列を返します。
	 * （マスク文字"*"）
	 * @param trgt マスク対象文字列
	 * @param fixed_flg 固定長フラグ
	 * @return String マスク化した文字列
	 */
	public static String stdMask(String trgt, boolean fixed_flg)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク対象文字列に全角文字が含まれるかチェックする。
		boolean zenkakuFlg = !(JCCStringChecker.isNarrowChar(trgt));
		//     ・全角文字が1つでも含まれる場合、マスク文字も全角とする。
		//     ・上記以外の場合、マスク文字を半角とする。
		// (3) 固定長フラグのチェックを行う。
		if(fixed_flg)
		{
			char maskChar = ' ';
			if(zenkakuFlg)
			{
				maskChar = MASK_ZENKAKU_CHAR_ASTERISK;
			}
			else
			{
				maskChar = MASK_CHAR_ASTERISK;
			}
		//     ・固定長フラグがtrueの場合、マスク対象文字列の桁数分のマスク文字の文字列を作成する。
		//        マスク化処理（ベース処理）メソッドを呼び出す
			StringBuffer trgtSb = new StringBuffer(trgt);
			try
			{
				trgtSb = maskBase(trgtSb, 0, trgtSb.length(), maskChar, NO_EXCLUDE_CHAR);
				return trgtSb.toString();
			}
			catch(IllegalArgumentException e)
			{
				return null;
			}
		}
		else
		{
		//     ・固定長フラグがfalseの場合、3桁のマスク文字の文字列を作成する。
			if(zenkakuFlg)
			{
				return FIXED_MASK_ZENKAKU_ASTERISK;
			}
			else
			{
				return FIXED_MASK_CHAR_ASTERISK;
			}
		}
	}
	
	/**
	 * No.2 マスク化標準処理（マスク文字"9"）
	 * マスク編集標準ルールに沿ったマスク化処理を行い、マスク化された文字列を返します。
	 * （対象文字列：半角 マスク文字："9"）
	 * @param trgt マスク対象文字列
	 * @param fixed_flg 固定長フラグ
	 * @return String マスク化した文字列
	 */
	public static String stdMaskAt9(String trgt, boolean fixed_flg)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"9"）
		try
		{
			if(fixed_flg)
			{
				StringBuffer trgtSb = new StringBuffer(trgt);
		//     ・固定長フラグがtrueの場合、マスク対象文字列の桁数分のマスク文字の文字列を作成する。
		//        マスク化処理（ベース処理）メソッドを呼び出す。
				trgtSb = maskBase(trgtSb, 0, trgtSb.length(), MASK_CHAR_9, NO_EXCLUDE_CHAR);
				return trgtSb.toString();
			}
			else
			{
		//     ・固定長フラグがfalseの場合、3桁のマスク文字の文字列を作成する。
				return FIXED_MASK_CHAR_9;
			}
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.3 パスワードマスク化処理
	 * パスワードのマスク化処理（8桁固定）を行い、マスク化された文字列を返します。
	 * （対象文字列：半角 マスク文字："*"）
	 * @return String マスク化した文字列
	 */
	public static String passWdMask()
	{
		// (1) マスク処理を行う。（マスク文字"*"）
		//     マスク文字8桁固定の文字列を返す。
		return PASSWORD_MASK_STRING;
	}
	
	/**
	 * No.4 マスク化処理(下4桁残し)
	 * マスク化対象文字列の下4桁以外のマスク化処理を行い、マスク化された文字列を返します。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String maskExcRight4(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"*"）
		StringBuffer trgtSb = new StringBuffer(trgt);
		try
		{
		//     マスク化処理（指定桁数残し）メソッドを呼び出す。
			trgtSb = maskExcRight(trgtSb, MASK_CHAR_ASTERISK, 4);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.5 マスク化処理（下4桁残し、かつハイフン残し）
	 * マスク化対象文字列の下4桁以外のマスク化処理を行い、マスク化された文字列を返します。
	 * ただし、マスク化対象文字列にハイフンが含まれる場合、それはマスク化しない。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String maskExcHypRight4(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		StringBuffer trgtSb = new StringBuffer(trgt);
		// (2) マスク処理を行う。（マスク文字"*"）
		try
		{
		//     ・マスク化処理（指定桁数残し、かつ指定文字残し）メソッドを呼び出す。
			trgtSb = maskExcCharAndRight(trgtSb, MASK_CHAR_ASTERISK, 4, CRECARD_NO_HYPHEN);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.6 クレジットカード番号マスク化標準処理
	 * クレジットカード番号のマスク化標準処理（ハイフンなしでかつすべてマスク化）を行い、
	 * マスク化された文字列を返します。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String stdCrecard(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		int trgtLen = trgt.length();
		StringBuffer trgtSb = new StringBuffer(trgt);
		// (2) マスク処理を行う。（マスク文字"*"）
		try
		{
		//     ・マスク化処理（ベース処理）メソッドを呼び出す
			trgtSb = maskBase(trgtSb, 0, trgtLen, MASK_CHAR_ASTERISK, NO_EXCLUDE_CHAR);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.7 クレジットカード番号マスク化処理（下4桁残し）
	 * クレジットカード番号の下4桁以外のマスク化処理（ハイフンなし）を行い、マスク化
	 * された文字列を返します。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String  マスク化した文字列
	 */
	public static String crecardExcRight4(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		StringBuffer trgtSb = new StringBuffer(trgt);
		// (2) マスク処理を行う。（マスク文字"*"）
		try
		{
		//     マスク化処理（指定桁数残し）メソッドを呼び出す。
			trgtSb = maskExcRight(trgtSb, MASK_CHAR_ASTERISK, 4);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}

	/**
	 * No.21 クレジットカード番号マスク化処理（上6桁、下4桁残し）
	 * クレジットカード番号の上6桁下4桁以外のマスク化処理（ハイフンなし）を行い、マスク化
	 * された文字列を返します。
	 * マスク化対象クレジットカード番号は14,15,16桁とする。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String  マスク化した文字列
	 */
	public static String crecardExcLeft6Right4(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		int trgtLen = trgt.length();
		if(!(CRECARD_NO_LENGTH_14 <= trgtLen && trgtLen <= CRECARD_NO_LENGTH_16))
		{
		//     ・マスク対象文字列の桁数が14桁、15桁、16桁のいずれにも該当しない場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		StringBuffer trgtSb = new StringBuffer();
		// (2) マスク処理を行う。（マスク文字"*"）
		try
		{
			trgtSb.append(trgt.substring(0, 6));
			int maskCharNum = trgtLen - 10;
			for (int i = 0; i < maskCharNum; i++)
			{
				trgtSb.append(MASK_CHAR_ASTERISK);
			}
			trgtSb.append(trgt.substring(trgtLen - 4));
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.8 クレジットカード番号マスク化処理（1ブロック残し）
	 * クレジットカード番号をハイフン編集を行い、ハイフンで区切られた最後尾の文字列以外の
	 * マスク化処理を行い、マスク化された文字列を返します。
	 * ただしハイフンはマスク化しない。また、マスク化対象クレジットカード番号は14,15,16桁とする。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String crecardExcBL1(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		int trgtLen = trgt.length();
		if(!(CRECARD_NO_LENGTH_14 <= trgtLen && trgtLen <= CRECARD_NO_HYPHEN_16))
		{
		//     ・マスク対象文字列の桁数が14桁、15桁、16桁のいずれにも該当しない場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		StringBuffer trgtSb = new StringBuffer(trgt);
		// (2) ハイフン編集を行う。
		try
		{
			if(!isHyphenEditing(trgtSb.toString()))
			{
		//     クレジットカード番号ハイフン編集メソッドを呼び出す。
				trgtSb = editCrecardNoHyphen(trgtSb);
			}
		// (3)  マスク処理を行う。（マスク文字"*"）
		//     ・マスク対象文字列からハイフン位置を取得し、マスク化する桁数を取得する。
			int hyphenIndex = trgtSb.lastIndexOf(String.valueOf(CRECARD_NO_HYPHEN));
		//     ・マスク化処理（ベース処理）メソッドを呼び出す
			trgtSb = maskBase(trgtSb, 0, hyphenIndex + 1, MASK_CHAR_ASTERISK, CRECARD_NO_HYPHEN);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.9 クレジットカード番号マスク化処理（ハイフン残し）
	 * クレジットカード番号をハイフン編集を行い、ハイフン以外のマスク化処理を行い、マスク化
	 * された文字列を返します。ただし、マスク化対象クレジットカード番号は14,15,16桁とする。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String crecardExcHyphen(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		int trgtLen = trgt.length();
		if(!(CRECARD_NO_LENGTH_14 <= trgtLen && trgtLen <= CRECARD_NO_HYPHEN_16))
		{
		//     ・マスク対象文字列の桁数が14桁、15桁、16桁のいずれにも該当しない場合、nullを返却し処理を終了する。
		//       ハイフン込みの場合、16桁、17桁、19桁のいずれかになる
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		StringBuffer trgtSb = new StringBuffer(trgt);
		// (2) ハイフン編集を行う。
		try
		{
			if(!isHyphenEditing(trgtSb.toString()))
			{
		//     クレジットカード番号ハイフン編集メソッドを呼び出す。
				trgtSb = editCrecardNoHyphen(trgtSb);
			}
		// (3) マスク処理を行う。（マスク文字"*"）
		//     ・マスク化処理（指定文字残し）メソッドを呼び出す。
			trgtSb = maskBase(trgtSb, 0, trgtSb.length(), MASK_CHAR_ASTERISK, CRECARD_NO_HYPHEN);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.10 クレジットカード有効期限マスク化標準処理
	 * クレジットカード有効期限のマスク化処理（すべてマスク化）を行い、マスク化された文字列を
	 * 返します。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String stdCrecardKigen(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(trgt.length() != 4)
		{
		//     ・マスク対象文字列の桁数が4桁以外の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"*"）
		StringBuffer trgtSb = new StringBuffer(trgt);
		try
		{
		//     ・マスク対象文字列の桁数分のマスク文字列を作成する。
		//        マスク化処理（ベース処理）メソッドを呼び出す
			trgtSb = maskBase(trgtSb, 0, trgtSb.length(), MASK_CHAR_ASTERISK, NO_EXCLUDE_CHAR);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.11 クレジットカード有効期限マスク化処理（スラッシュ残し）
	 * スラッシュ編集されたクレジットカード有効期限のマスク化処理（すべてマスク化）を行い、
	 * マスク化された文字列を返します。ただしスラッシュはマスク化しない。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String crecardKgnExcSlash(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(trgt.length() != 5)
		{
		//     ・マスク対象文字列の桁数が5桁以外の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"*"）
		StringBuffer trgtSb = new StringBuffer(trgt);
		try
		{
		//     ・マスク化処理（指定文字残し）メソッドを呼び出す。
			trgtSb = maskBase(trgtSb, 0, trgtSb.length(), MASK_CHAR_ASTERISK, CRECARD_KGN_SLASH);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.12 クレジットカード有効期限マスク化処理（スラッシュ削除）
	 * スラッシュ編集されたクレジットカード有効期限のマスク化処理（すべてマスク化）を行い、
	 * マスク化された文字列を返します。ただしスラッシュは削除する。
	 * （対象文字列：半角 マスク文字："9"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String crecardKgnDelSlash(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(trgt.length() != 5)
		{
		//     ・マスク対象文字列の桁数が5桁以外の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"9"）
		StringBuffer trgtSb = new StringBuffer(trgt);
		//     ・マスク対象文字列に含まれるスラッシュを削除する。
//		trgtSb.replace(0, trgtSb.length(), String.valueOf(CRECARD_KGN_SLASH));
		int index = 0;
		while(index >= 0)
		{
			index = trgtSb.indexOf(String.valueOf(CRECARD_KGN_SLASH), index);
			if(index >= 0)
			{
				trgtSb.deleteCharAt(index);
				index++;
			}
		}
		try
		{
		//     ・マスク対象文字列の桁数分のマスク文字列を作成する。
		//        マスク化処理（ベース処理）メソッドを呼び出す
			trgtSb = maskBase(trgtSb, 0, trgtSb.length(), MASK_CHAR_9, NO_EXCLUDE_CHAR);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.15 電話番号マスク化処理
	 * 電話番号の種別を判定し、それに合わせたマスク化を行った文字列を返します。
	 * マスク化対象外の電話番号が指定された場合、その電話番号をそのまま返します。
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String telNoExt(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNumeric(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) 電話番号判定処理
		String retValue = "";
		int trgtLength = trgt.length();
		// No.1 4桁以下
		if(trgtLength <= 4)
		{
			// 3桁番号サービス（177など）
			retValue = trgt;
		}
		// No.2 5〜8桁
		else if(5 <= trgtLength && trgtLength <= 8)
		{
			char first = trgt.charAt(0);
			char second = trgt.charAt(1);
			// 1桁目が'0' かつ 2桁目が'0'以外
			if(first == '0' && second != '0')
			{
				// 各地の天気予報
				retValue = trgt;
			}
			else if(first == '0' && second == '0')
			{
				// KDDIフリーコール
				retValue = telNoTrgtRight4(trgt);
			}
			else if(first != '0')
			{
				// 固定電話（市外局番なし）
				retValue = telNoTrgtRight4(trgt);
			}
		}
		// 9〜10桁
		else if(9 <= trgtLength && trgtLength <= 10)
		{
			// 固定電話（市外局番あり）、その他フリーコール
			retValue = telNoTrgtRight4(trgt);
		}
		else
		{
			// 携帯電話、国際電話、携帯電話+プッシュフォン
			retValue = telNo(trgt);
		}
		return retValue;
	}
	
	/**
	 * No.14 電話番号マスク化処理（8桁目から4桁）
	 * 電話番号のマスク化処理（8桁目から4桁）を行い、マスク化された文字列を返します。
	 * ただし、国際通話（11桁越）および通常電話+プッシュボタンを押しているものを対象とする。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String telNo(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(trgt.length() < 11)
		{
		//     ・マスク対象文字列の桁数が11桁未満の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"*"）
		StringBuffer trgtSb = new StringBuffer(trgt);
		try
		{
		//     ・マスク対象文字列の8桁目から4桁をマスク化する。
		//        マスク化処理（ベース処理）メソッドを呼び出す
			trgtSb = maskBase(trgtSb, 7, 4, MASK_CHAR_ASTERISK, NO_EXCLUDE_CHAR);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.15 電話番号マスク化処理（下4桁マスク化）
	 * 電話番号の下4桁のマスク化処理を行い、マスク化された文字列を返します。
	 * ただし、国内固定電話(10桁)、国内固定電話(市外局番なし:5〜8桁)、国内携帯電話(11桁)、
	 * KDDIフリーコールを対象とする。
	 * （対象文字列：半角 マスク文字："*"）
	 * @param trgt マスク対象文字列
	 * @return String マスク化した文字列
	 */
	public static String telNoTrgtRight4(String trgt)
	{
		// (1) チェック処理
		if(trgt == null || "".equals(trgt))
		{
		//     ・マスク対象文字列がnullまたは空文字("")の場合、nullを返却し処理を終了する。
			return null;
		}
		if(trgt.length() < 5)
		{
		//     ・マスク対象文字列の桁数が5桁未満の場合、nullを返却し処理を終了する。
			return null;
		}
		if(!(JCCStringChecker.isNarrowChar(trgt)))
		{
		//     ・マスク対象文字列に全角文字が含まれている場合、nullを返却し処理を終了する。
			return null;
		}
		// (2) マスク処理を行う。（マスク文字"*"）
		StringBuffer trgtSb = new StringBuffer(trgt);
		//     ・マスク対象文字列の下4桁目以降をマスク化する。
		//        マスク化処理（ベース処理）メソッドを呼び出す
		try
		{
			trgtSb = maskBase(trgtSb, trgtSb.length() - 4, 4, MASK_CHAR_ASTERISK, NO_EXCLUDE_CHAR);
			return trgtSb.toString();
		}
		catch(IllegalArgumentException e)
		{
			return null;
		}
	}
	
	/**
	 * No.16 マスク化処理（指定桁数残し）
	 * 対象文字列の右から指定された桁数分だけ残して、それ以外をすべて指定されたマスク文字で
	 * 置き換えます。
	 * @param trgt マスク対象文字列
	 * @param mask_char マスク文字列
	 * @param right 対象文字列の右残す分だけの文字数 1からマスク対象文字列長さまで
	 * @return StringBuffer マスク化した文字列
	 * @exception IllegalArgumentException
	 */
	private static StringBuffer maskExcRight(StringBuffer trgt, char mask_char, int right) throws IllegalArgumentException
	{
		// (1) チェック処理
		if(trgt == null || trgt.length() == 0)
		{
		//     ・マスク対象文字列がnullまたはサイズが0の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		if(right == 0 || trgt.length() <= right)
		{
		//     ・対象文字列の右残す分だけの文字数が0またはマスク対象文字列のサイズより大きい場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		// (2) マスク処理を行う。（マスク文字引数で指定された文字）
		//     ・マスク対象文字列の右から指定された桁数分だけ残して、それ以外をすべてマスク化する。
		//        マスク化処理（ベース処理）メソッドを呼び出す
		return maskBase(trgt, 0, trgt.length() - right, mask_char, NO_EXCLUDE_CHAR);
	}
	
	/**
	 * No.17 マスク化処理（ベース処理）
	 * 対象文字列を指定された位置から指定された桁数分指定されたマスク文字で置き換えます。
	 * また、置換え不要文字が指定されている場合、それに従う。
	 * @param trgt マスク対象文字列
	 * @param start マスク化開始位置 0からマスク対象文字列長さ-1
	 * @param len マスク桁数
	 * @param mask_char マスク文字
	 * @param exc_char マスク除外文字
	 * @return StringBuffer マスク化した文字列
	 * @exception IllegalArgumentException
	 */
	private static StringBuffer maskBase(StringBuffer trgt, int start, int len, char mask_char, char exc_char) throws IllegalArgumentException
	{
		// (1) チェック処理
		if(trgt == null || trgt.length() == 0)
		{
		//     ・マスク対象文字列がnullまたはサイズが0の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		if(trgt.length() <= start)
		{
		//     ・マスク化開始位置がマスク対象文字列のサイズ以上の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		if(trgt.length() < start + len)
		{
		//     ・マスク桁数がマスク対象文字列のサイズとマスク化開始位置との間で矛盾がある場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		// (2) マスク処理を行う。（マスク文字引数で指定された文字）
		for(int iCnt = start; iCnt < start + len; iCnt++)
		{
		//     ・指定されたマスク化開始位置からマスク桁数分、指定されたマスク文字でマスク化する。
		//     ・マスク除外文字は、マスク化対象外とする。
			char trgtChar = trgt.charAt(iCnt);
			if(trgtChar != exc_char || NO_EXCLUDE_CHAR == exc_char)
			{
				trgt.setCharAt(iCnt, mask_char);
			}
		}
		return trgt;
	}
	
	/**
	 * No.18 クレジットカード番号ハイフン編集
	 * クレジットカード番号のハイフン編集を行う。ただし、桁数による固定的なハイフン編集とする。
	 * @param trgt 編集対象文字列
	 * @return StringBuffer 編集後の文字列
	 * @exception IllegalArgumentException
	 */
	private static StringBuffer editCrecardNoHyphen(StringBuffer trgt) throws IllegalArgumentException
	{
		// (1) チェック処理
		if(trgt == null || trgt.length() == 0)
		{
		//     ・編集対象文字列がnullまたはサイズが0の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		int trgtLen = trgt.length();
		if(trgtLen != CRECARD_NO_LENGTH_14 && trgtLen != CRECARD_NO_LENGTH_15 && trgtLen != CRECARD_NO_LENGTH_16)
		{
		//     ・編集対象文字列のサイズが14、15、16桁以外の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		// (2) ハイフン編集を行う。
		switch(trgtLen)
		{
			case CRECARD_NO_LENGTH_14:
		//     ・14桁の場合、9999-999999-9999(4桁-6桁-4桁)
				trgt.insert(4, CRECARD_NO_HYPHEN).insert(11, CRECARD_NO_HYPHEN);
				break;
				
			case CRECARD_NO_LENGTH_15:
		//     ・15桁の場合、9999-999999-99999(4桁-6桁-5桁)
				trgt.insert(4, CRECARD_NO_HYPHEN).insert(11, CRECARD_NO_HYPHEN);
				break;
				
			case CRECARD_NO_LENGTH_16:
		//     ・16桁の場合、9999-9999-9999-9999(4桁-4桁-4桁-4桁)
				trgt.insert(4, CRECARD_NO_HYPHEN).insert(9, CRECARD_NO_HYPHEN).insert(14, CRECARD_NO_HYPHEN);
				break;
				
			default :
				throw new IllegalArgumentException();
		}
		return trgt;
	}
	
	/**
	 * No.19 マスク化処理（指定桁数残し、かつ指定文字残し）
	 * 対象文字列の右から指定された桁数分だけ残して、それ以外をすべて指定されたマスク文字で置き換えます。
	 * ただし、マスク除外として指定された文字は、マスク文字で置き換えない。
	 * @param trgt マスク対象文字列
	 * @param mask_char マスク文字列
	 * @param right 対象文字列の右残す分だけの文字数
	 * @param exc_char マスク除外文字
	 * @return StringBuffer 編集後の文字列
	 * @exception IllegalArgumentException
	 */
	private static StringBuffer maskExcCharAndRight(StringBuffer trgt, char mask_char, int right, char exc_char) throws IllegalArgumentException
	{
		// (1) チェック処理
		if(trgt == null || trgt.length() == 0)
		{
		//     ・マスク対象文字列がnullまたはサイズが0の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		if(right == 0 || trgt.length() <= right)
		{
		//     ・対象文字列の右残す分だけの文字数が0またはマスク対象文字列のサイズより大きい場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		// (2) マスク処理を行う。（マスク文字引数で指定された文字）
		//     ・指定されたマスク化開始位置からマスク桁数分、指定されたマスク文字でマスク化する。
		//     ・マスク除外文字は、マスク化対象外とする。
		//        マスク化処理（ベース処理）メソッドを呼び出す
		return maskBase(trgt, 0, trgt.length() - right, mask_char, exc_char);
	}
	
	/**
	 * No.20 ハイフン編集検査処理
	 * クレジットカード番号のハイフン編集が行われているか検査する。
	 * @param trgt_sb  検査対象文字列
	 * @return boolean true：ハイフン編集済み false：ハイフン編集なし
	 */
	private static boolean isHyphenEditing(String trgt_sb)
	{
		boolean retValue = false;
		
		// (1) チェック処理
		if(trgt_sb == null || trgt_sb.length() == 0)
		{
		//     ・検査対象文字列がnullまたはサイズが0の場合、IllegalArgumentExceptionをスローする。
			throw new IllegalArgumentException();
		}
		// (2) ハイフン編集のチェックを行う。
		int index = trgt_sb.indexOf(String.valueOf(CRECARD_NO_HYPHEN));
		//     ・検査対象文字列にハイフンが含まれるかチェックする。
		if(index != -1)
		{
			retValue = true;
		}
		return retValue;
	}
}
