      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