2009年10月31日 星期六

Leet

 
多年前剛接觸 C++ 時寫的程式,
用來將輸入字串轉成 Hacker 用語,
code 很舊了,不包含近來的替換形式,
基本轉換規則見: http://wapedia.mobi/zh/Leet

#include <iostream.h>
#include <stdio.h>
#include <time.h>

typedef short int S2B;

class Leet
{
   static long int s_;          
   static int _(int n) {
       s_ *= 0x15a4e35; ++s_;
       return ((s_>>16)&0x7fff) % n;
   }
   static struct Ltbl {
       S2B    n;                     //替換字串的單詞數     
       char*  s;                     //替換字串
   } ltbl[26], term[36];             //字元替換表, 與單詞替換表
   static S2B  termPos[26];          //紀錄字元所對應到的第一個
                                     //單詞的開頭位置
public:
   static void translate (char*);    //進行字串替換
   Leet();                           //初始化函式
};

long int Leet::s_=0;
S2B Leet::termPos[26];

Leet::Ltbl Leet::ltbl[26] =          //建立替換字元表
{
   4,"A a 4 @ ",  4,"B b 6 8 ",  4,"C c < K ",  
   4,"D d |> |) ",  3,"E e 3 ",  2,"F f ",  
   3,"G g 9 ",   3,"H h # ",   5,"I i 1 y | ",  
   2,"J j ",   3,"K k |< ",   4,"L l 1 |_ ",  3,"M m |\\/| ",  
   3,"N n h ", 3,"O o 0 ",  2,"P p ",  2,"Q q ",  
   2,"R r ",  5,"S s 5 z $ ",  4,"T t 7 + ",  5,"U u |_| O o ",  
   5,"V v |/ \\/ / ",  4,"W w \\/\\/ // ",  
   3,"X x >< ",  3,"Y y j ",  3,"Z z 2 "
};                                   //建立單詞替換表
Leet::Ltbl Leet::term[36] = 
{
   1, "at @ ",
   2, "cool kewl kool ",
   1, "dude dOOd ",
   1, "dudes dOOdz ",
   4, "drugs drugz drugz droogs droogz ",
   4, "ellet 31337 1337 leet elite ",
   4, "elite 31337 1337 leet elite ",
   2, "god root sysop ",
   2, "hacker h4X0r haxor ",
   2, "have G0tz gots ",
   1, "hello 43770 ",
   8, "i eye 3y3 ey3 3ye i | 1 y ",
   3, "information info 411 four-eleven ",
   2, "info 411 four-eleven ",
   1, "let 137 ",
   1, "love luv ",
   1, "microsoft M$ ",
   6, "of u|/ |_|V U/ uv |_||/ ",
   1, "peasant pissant ",
   3, "please pleez pleeze pleze ",
   1, "phone fone ",
   2, "porn pr0n pron ",
   1, "porno pr0n0 ",
   3, "poser pozer poseur pozeur ",
   2, "pot pott p0t ",
   1, "root god ",
   1, "see c ",
   3, "the Da D4 4 ",
   1, "to 2 ",
   1, "too 2 ",
   5, "you u U j0O Joo |_| ",
   3, "your j0r jo joor ",
   0, "{ "
};

Leet::Leet()     //初始化函式
{
   if (!s_) {
      s_ = time(0);
      for (int j=0, i=0; i<26; i++) {         //紀錄各字首在 term[] 
         while (*term[j].s < i+'a') j++;      //中的起始位置
         if (*term[j].s^ i+'a') {
             termPos[i] = -1; 
             continue;
         }
         termPos[i] = j; 
      }
   }
}
void Leet::translate (char* s)
{  
   int  n, i,j;  Ltbl* p;  
   bool bInWord = 0;                          //當字串指標 ps 指向字串 
   char *ps2,*ps=s;                           //開頭時,bInWord = false

   do if (*ps>='A' && *ps<='Z')               //先將字串轉成小寫
         *ps += ('a'-'A'); 
   while (*ps++);

   do {
      n = *s; 
      if (n>='a' && n<='z')  n-='a';          //將小寫轉成 0~25, 
      else {                                  //非字母者直接印出
          if(n=='`') cout<<'\\';  
          cout<<*s; bInWord=0;  
          continue;
      }   
          //單詞判讀:

      if (termPos[n]==-1 || bInWord) 
          goto AC;                            //"alpha chg" 之意

      p = term + termPos[n];
      for (;*p->s == *s; p++)                 //比對相同字首的單詞
      {
         ps = p->s;  ps2 = s;                 //使用字串指標加快運算速度
         while (*ps^' ' && *ps++ == *ps2++);  //持續比對至遇到空白
         if (*ps == *ps2)  break;             //若遇到相符的樣式便結束比對
      }
      if (*p->s^*s ||_(2))  goto AC;          //若無相關單詞, 便直接做字元轉換
      
      n = _(p->n) + 1;
      for (j=i=0; i<n; i++)  
          while (p->s[j++]^' ');
      
      while (p->s[j]^' ')                     //持續輸出字元,
          cout << p->s[j++];                  //直到遇到空白
      s = ps2 - 1;  
      bInWord = 0;  
      continue;                               //單詞判讀成功

          //字元判讀:
AC:   
      p = ltbl + n;
      n = _(p->n);
      for (j=i=0; i<n; i++)  
          while (p->s[j++]^' ');

      while (p->s[j]^' ')                     //持續輸出字元,
          cout << p->s[j++];                  //直到遇到空白
      bInWord = true;
   }
   while(*s++);
}

void main()
{
   Leet leet;                                 //建立物件
   char buf[1024]; 
   gets (buf);                                //讀取字串
   leet.translate (buf);                      //進行轉換
}

沒有留言:

張貼留言