1 
  2 /**
  3  * @name	CeL check function
  4  * @fileoverview
  5  * 本檔案包含了 check 處理的 functions。
  6  * @since	
  7  */
  8 
  9 
 10 if (typeof CeL === 'function')
 11 CeL.setup_module('data.check',
 12 function(library_namespace, load_arguments) {
 13 
 14 //	nothing required
 15 
 16 
 17 /**
 18  * null module constructor
 19  * @class	check 處理的 functions
 20  */
 21 CeL.data.check
 22 = function() {
 23 	//	null module constructor
 24 };
 25 
 26 /**
 27  * for JSDT: 有 prototype 才會將之當作 Class
 28  */
 29 CeL.data.check
 30 .prototype = {
 31 };
 32 
 33 
 34 
 35 /*	國際標準書號check	2004/11/22 20:
 36 	http://zh.wikipedia.org/wiki/ISBN
 37 	http://www.hkpl.gov.hk/tc_chi/books_reg/books_reg_n13d/books_reg_n13d.html
 38 	http://www.isbn-international.org/converter/converter.html
 39 	http://www.isbn.org/converterpub.asp
 40 	輸入ISBN可test是否正確,若輸入不完全的(僅缺校驗碼check digit),則會輸出完全碼
 41 
 42 	[3]國別語種識別代號:用以識別出版社所屬的國家、語文、地域等。香港的代號是「962」或「988」。
 43 	[3]出版社識別代號:識別某一出版社。
 44 	[3]書名版別代號:由出版社自行為新出版的書種或版本編配。
 45 	[1]稽核數碼:用以核對書號是否正確。
 46 	每部分由連字號或空位分隔。
 47 
 48 常用check法: for 1652
 49 checksum:1+6+5+2(mod 10)
 50 質數除法:1652(mod prime)
 51 modulus & weight(模數與權數):ISBN等, 1*9+6*8+5*7+2*6(mod p)
 52 
 53 */
 54 function checkISBN10(code) {
 55 	if (!/^\d{9}[\dxX]?$/.test(code = ('' + code).replace(/[-\s]/g, '')))
 56 		return;
 57 	// c:check digit
 58 	var i = 0, c = 0;
 59 	for (; i < 9;)
 60 		c += code.charAt(i++) * i;
 61 	c %= 11;
 62 	if (c === 10)
 63 		c = 'X';
 64 	return code.length == 9 ? code + c : c === (i = code.charAt(9))
 65 			|| c === 'X' && i === 'x';
 66 }
 67 //	2006/11/8 19:09
 68 function checkISBN13(code) {
 69 	if (!/^\d{12,13}$/.test(code = ('' + code).replace(/[-\s]/g, '')))
 70 		return;
 71 	var i = 1, c = 0; // c:check digit
 72 	for (; i < 12; i += 2)
 73 		c += Math.floor(code.charAt(i));
 74 	for (c *= 3, i = 0; i < 12; i += 2)
 75 		c += Math.floor(code.charAt(i));
 76 	c = (220 - c) % 10; //	220:大於(1*6+3*6),%10==0即可。
 77 	return code.length == 12 ? code + c : c == code
 78 			.charAt(12);
 79 }
 80 
 81 /*	臺灣地區國民身份證代字 Identity Card No. check	2004/11/22 22:31
 82 	輸入身份證號碼可test是否正確,若輸入不完全的(僅缺檢查碼),則會輸出完全碼
 83 var checkTWIDC='ABCDEFGHJKLMNPQRSTUVXYWZIO',checkTWIDCity='臺北市,臺中市,基隆市,臺南市,高雄市,臺北縣,宜蘭縣,桃園縣,新竹縣,苗栗縣,臺中縣,南投縣,彰化縣,雲林縣,嘉義縣,臺南縣,高雄縣,屏東縣,花蓮縣,臺東縣,澎湖縣,陽明山,,,嘉義市,新竹市'.split(',');	//	checkTWIDCity:代號表
 84 */
 85 function checkTWID(ID,city,sex){	//	提供city/sex時ID只需要輸入流水號
 86  ID=('' + ID).replace(/ /g,'').toUpperCase();
 87  if(sex)ID=(sex=sex=='男'?1:sex=='女'?2:sex)+ID;
 88  var i,c;	//	check digit
 89  if(city&&(i=(c=checkTWIDCity.join(',')).indexOf(''+city))!=-1)
 90   i=c.slice(0,i),city=i.length-i.replace(/,/g,'').length;
 91  if(isNaN(city))city=checkTWIDC.indexOf(ID.charAt(0));else ID=checkTWIDC.charAt(city)+ID;
 92  if(!/^[A-Z][12]\d{7,8}$/.test(ID))return;
 93  if(!sex)sex=ID.charAt(1)==1?'男':'女';
 94 
 95 
 96 /*	old:網路上流傳的演算法,slow
 97  c=''+(10+city),c=9*c.charAt(1)+parseInt(c.charAt(0));
 98  for(i=1;i<9;i++)c+=(9-i)*ID.charAt(i);
 99  c%=10;
100  if(ID.length==10&&parseInt(ID.charAt(9))+c!=10)return null;
101  if(ID.length==9)ID+=10-c;
102 */
103 
104  for(i=1,c=city,c+=9-(c-c%10)/10;i<9;)c+=ID.charAt(i++)*i;
105  c%=10;
106  if(ID.length==10){if(ID.charAt(9)!=c)return null;}else if(ID.length==9)ID+=c;
107 
108  return [ID,checkTWIDCity[city],sex,c];
109 }
110 //	check only
111 function checkTWIDNo(ID) {
112 	var i = 1, c = 'ABCDEFGHJKLMNPQRSTUVXYWZIO'.indexOf(ID.charAt(0).toUpperCase());
113 	for (c += 9 - (c - c % 10) / 10; i < 9;)
114 		c += ID.charAt(i++) * i;
115 	return c % 10 == ID.charAt(9);
116 }
117 
118 
119 
120 
121 
122 /*	判斷キリ番等,counter專用	2004/8/26 20:14
123 	キリ番ゲッターidお名前(げっちゅ~)	home	mail	num	キリである理由	ip	date	msg	point(得點)
124 	キリ番 2000 まで、あと 265 です。ゲットは推定 5月31日(金) 9:17 頃です。	キリの良い番号(キリ番)・数字の揃った番号(ゾロ目)または語呂の良い番号(ゴロ番、面白く読める番号)を踏んだ方
125 	還可以加的:445533等
126 */
127 var isLuckyNum_dDigit=3;	//	最低位數downmost digit>1
128 function isLuckyNum(num){	//	return luck kind
129  if(!/^\d{1,20}$/.test(num)){alert();return;}
130  num=parseInt(num,10);
131  if(!num||num<1)return;
132  if(typeof num!=='string')
133 	 num=String(num);
134  if(!isLuckyNum_dDigit||isLuckyNum_dDigit<2)isLuckyNum_dDigit=3;	//	default
135  //if(num.length==1)return '首十位';
136  if(num.length<isLuckyNum_dDigit)return;
137  if(num.match(new RegExp('(0{'+isLuckyNum_dDigit+',})$')))return '下'+RegExp.$1.length+'桁のキリ番';
138  if(num.match(new RegExp('(9{'+isLuckyNum_dDigit+',})$')))return '前後賞:差一'+(1+RegExp.$1.length)+'位數整~';
139  if(num.match(new RegExp('(0{'+(isLuckyNum_dDigit-1)+',}1)$')))return '前後賞:'+(1+RegExp.$1.length)+'位數過一~';
140  if(num.match(new RegExp('('+num.slice(-1)+'{'+isLuckyNum_dDigit+',})$')))return '下'+RegExp.$1.length+'桁のゾロ目';
141 
142  var i=2,c=Math.floor(num.charAt(0)),d=num.charAt(1)-c;c+=d;
143  while(i<num.length)if(num.charAt(i++)!=(c+=d)){d=0;break;}
144  if(d)return '連番(公差'+d+'の等差数列)';
145 
146  i=2,c=Math.floor(num.charAt(0)),d=num.charAt(1)/c;c*=d;
147  while(i<num.length)if(num.charAt(i++)!=(c*=d)){d=0;break;}
148  if(d)return '公比'+(d>1?d:'1/'+(1/d))+'の等比数列';
149 
150  if( num.length>=isLuckyNum_dDigit){
151   c=Math.floor(num.length/2),d=1;
152   if(num.slice(0,c)==num.substr(num.length-c))return c+'桁の対称形';
153 
154   for(i=0;i<=c;i++)if(num.charAt(i)!=num.charAt(num.length-1-i)){d=0;break;}
155   if(d)return c+'桁の左右対称(鏡像、シンメトリィ)';
156 
157   for(i=2;i<=c;i++){
158    d=num.slice(0,i);var s=d;while(s.length<num.length)s+=d;
159    if(num==s.slice(0,num.length))return i+'位數循環/回文';
160   }
161 
162   for(i=2,c=Math.floor(num.charAt(0)),d=Math.floor(num.charAt(1));i<num.length;i++)
163    if(num.charAt(i)==c+d)c=d,d=Math.floor(num.charAt(i));else{d=0;break;}
164   if(d)return 'Fibonacci数列';
165  }
166 
167 }
168 
169 
170 
171 
172 
173 return (
174 	CeL.data.check
175 );
176 }
177 
178 
179 );
180 
181