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