<?php
/**
 * 広告コード暗号化・複合化クラス。
 * $Id: XcodeCryptor.inc,v 1.1 2015/10/08 11:18:56 wanggb Exp $
 * @author hr_wanggb
 * @access  public
 * @package jp.aimslib2.util
 */


class XcodeCryptor {
	
	/**
	 * 暗号化テーブル
	 *
	 * @return Array
	 */
	public static function getBaseArray() {
		$base_string = "0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z";
					// "W z x 3 s 5 6 K 2 l M B C 7 N h G H d J P i A b 8 E Q R S _ U 4 I X u e n D F c 0 Z f g 9 O Y k r L m o t q w p V T v a 1 y j";
		$base_array = explode(" ", $base_string);
		
		return $base_array;
	}
	
	/**
	 * 暗号化テーブル
	 *
	 * @return Array
	 */
	public static function getConvertArray() {
		$convert_string = "W z x 3 s 5 6 K 2 l M B C 7 N h G H d J P i A b 8 E Q R S _ U 4 I X u e n D F c 0 Z f g 9 O Y k r L m o t q w p V T v a 1 y j";
		
		$convert_array = explode(" ", $convert_string);
		
		return $convert_array;
	}
	
	/**
	 * ユーザIDとバナーIDをくっつけて複合化します。
	 * @return String 暗号化した文字列
	 */
	public static function encode($user_id, $site_id, $banner_id) {
		
		if (!is_numeric($site_id)) {
			ErrorLogger::doOutput("Error: site_id is not numeric", 0, "XcodeCryptor");
			return null;
		}
		if (!is_numeric($banner_id)) {
			ErrorLogger::doOutput("Error: banner_id is not numeric", 0, "XcodeCryptor");
			return null;
		}
		if ($site_id < 1) {
			ErrorLogger::doOutput("Error: site_id must be larget than 1.", 0, "XcodeCryptor");
			return null;
		}
		
		
		// ユーザーIDの長さ 最大99
		$user_id_len = sprintf("%02d", strlen("" . $user_id));
		// 番組IDの長さ 最大16
		$site_id_len = strlen("" . $site_id);
		
		if ($site_id_len > 16) {
			ErrorLogger::doOutput("Error: site_id length exceeds max of 16", 0, "XcodeCryptor");
			return null;
		}
		//ErrorLogger::doOutput("user_id_len:" . $user_id_len . " site_id_len:" . $site_id_len, 0, "XcodeCryptor");
		if ($user_id_len > 99) {
			ErrorLogger::doOutput("Error: user_id length exceeds max of 99", 0, "XcodeCryptor");
			return null;
		}
		$len_str = $site_id_len . $user_id_len;
		$len_str_con = base_convert($len_str, 10, 16);
		
		$mid_len = strlen("" . $len_str_con);

		
		$base_array = XcodeCryptor::getBaseArray();
		$convert_array = XcodeCryptor::getConvertArray();
		
		$new_user_id = "";
		
		// これも暗号化する。長さはかわらない
		$new_len_str_con = XcodeCryptor::charReplaceNonRecursive($base_array, $convert_array, $len_str_con);
		//ErrorLogger::doOutput("convert len_str:" . $len_str_con . "-" . $new_len_str_con, 0, "XcodeCryptor");
		
		// user_idの暗号化
		if (strlen($user_id) > 0) {
			$new_user_id = XcodeCryptor::charReplaceNonRecursive($base_array, $convert_array, $user_id);
		}
		
		
			
		// site_id banner_id暗号化
		$string = base_convert($site_id . "" . $banner_id, 10, 16);
		$return_string = $mid_len . $new_len_str_con . $new_user_id . $string;
		return $return_string;
	}

	/**
	 * 暗号化された値をuser_idとbanner_idに複合化します。
	 * @param String $x_code 暗号化された文字列
	 * @retrun array (user_id, $site_id, banner_id)からなる配列
	 */
	public static function decode($x_code) {

//		// user_id暗号化用
//		$can_use_string = "0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z";
//		$convert_string = "W z x 3 s 5 6 K 2 l M B C 7 N h G H d J P i A b 8 E Q R S _ U 4 I X u e n D F c 0 Z f g 9 O Y k r L m o t q w p V T v a 1 y j";
//		
//		$base_array = explode(" ", $can_use_string);
//		$convert_array = explode(" ", $convert_string);
		
		$base_array = XcodeCryptor::getBaseArray();
		$convert_array = XcodeCryptor::getConvertArray();
		
		$mid_len = substr($x_code, 0, 1);
		$len_str = substr($x_code, 1, $mid_len);
		
		// これも複合化する。長さはかわらない
		$new_len_str = XcodeCryptor::charReplaceNonRecursive($convert_array, $base_array, $len_str);
		//ErrorLogger::doOutput("convert len_str:" . $len_str . "-" . $new_len_str, 0, "XcodeCryptor");
		
		$len_str_con = base_convert($new_len_str, 16, 10);
		$user_id_len = substr($len_str_con, 1, 2);
		$site_id_len = substr($len_str_con, 0, 1);
		
		//ErrorLogger::doOutput("mid_len:" . $mid_len, 0, "XcodeCryptor");
		//ErrorLogger::doOutput("len_str:" . $len_str, 0, "XcodeCryptor");
		//ErrorLogger::doOutput("user_id_len:" . $user_id_len, 0, "XcodeCryptor");
		
		$new_user_id = substr($x_code, $mid_len + 1, $user_id_len);
		//ErrorLogger::doOutput($x_code . " new_user_id:" . $new_user_id, 0, "XcodeCryptor");
		
		$string = base_convert(substr($x_code, $mid_len + 1 + $user_id_len), 16, 10);
		//ErrorLogger::doOutput($x_code . " site_id convert:" . substr($x_code, $mid_len + 1 + $user_id_len) . " " . $string, 0, "XcodeCryptor");
		$site_id = substr($string, 0, $site_id_len);
		$banner_id = substr($string, $site_id_len);

				
		$user_id = "";
		// user_idの複合化
		if (strlen($new_user_id) > 0) {
			$user_id = XcodeCryptor::charReplaceNonRecursive($convert_array, $base_array, $new_user_id);
		}
		
		
		return array($user_id, $site_id, $banner_id);
	}
	
	
	/**
	 * 再帰的置換を行わないstr_replace
	 *
	 * @param Array $search
	 * @param Array $replace
	 * @param String $subject
	 * @return String
	 */
	public static function charReplaceNonRecursive($search, $replace, $subject) {
		
		$result = "";

		for($i = 0; $i < strlen($subject); $i++) {
			$char = substr($subject, $i, 1);
			$match = false;
			for ($x = 0; $x < count($search); $x++) {
				
				if ($char == $search[$x]) {
					$result .= $replace[$x];
					$match = true;
					break;
				}
			}
			if (!$match) {
				$result .= $char;
			}
			
		}
		
		
		return $result;
	}
}

?>