Zeray Rice

..

Myqq3代碼研究

前幾天突然想到要寫個QQ的機器人 因為之前用IMified寫過gtalk msn的機器人 但是 這個平台不提供QQ的機器人..只能自己找找看了 在google上搜了好久 沒搜到個能用的 於是想到在蟹爪上問阿黃 阿黃說可以用 小蝦的 myqq3 於是我就奔過去下載了下來

今天開始翻源碼來看 找到main在myqq.c裡 從這裡開始看

1
2
3
4
5
6
int main(int argc, char** argv)
{
  int cmdid, lastcmd=-1, len;
  char cmd[16], arg[1008];
  srand(time(NULL));
}

變量定義先不說 先說下srand(time(NULL)); 呃 其實一開始我沒看出來這是幹嘛用的 不過慢慢查函數才知道 是用來產生隨機數的 不過這個隨機數沒有賦給任何變量 按理說應該是沒有用的代碼 給ceeji神牛說了後 才知道 和隨機數的產生算法有關——「線性同於法」 :

假设I就是一个随机数的序列,Ij+1与Ij的关系如下:

Ij+1 =Ij * a+c (mod m)

或是Ij+1 =Ij *a (mod m),

也就是說 每一個產生的隨機數 都和上一個產生的隨機數有關 而且 普通計算機產生的 隨機數都不是真正的隨機數 而是所謂的「偽隨機數」 下面還有一段話 說

您可以制造某种设备,用其监视完全随机的自然事件,然后将事件结果发送给计算机。例如,您可以在盖革计数器前放置一片放射性物质,并将盖革计数器连接到计算机。因为放射性衰变是随机的,所以盖革计数器将生成真正的随机数。这种方法的使用很罕见,因为并没有太多人在自己的计算机上连有盖革计数器。

不過= =我覺得 裝這個蓋革計數器 應該很貴吧… 不知道我朝山寨軍裡 有沒有 很好的類似的產品(哎呀 又說遠了 反正我也不需要這玩意兒…)

順便 今天在搜索的時候 發現 stdlib.h裡面有這樣的語句

1
2
#define random(num) (rand() % (num))
#define randomize() srand((unsigned)time(NULL))

也就是說 要生成指定範圍的隨機數的話 不用 在用這樣的程序了

1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main( void )
{
  srand((unsigned)time(NULL));
  printf( " %d\n", rand()%10  );
  return 0;
}

像這樣的程序可以直接改成

1
2
3
4
5
6
7
8
9
10
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main( void )
{
  srand((unsigned)time( NULL ));
  printf( " %d\n", random( 10 ) );
  return 0;
}

這個樣子了 不用再去 取餘什麼的= = (不過我也沒覺得方便到哪去)

對了 突然想起了個 前一段查資料的時候 看到一個說法 說是在#include 的時候 用 “” 括住的頭文件 編譯器會先從 源文件所在的文件夾找這個頭文件 而用<>括住的 頭文件 會先從系統的環境變量裡去找 嗯 以後記得注意這一點

接著說myqq3 嗯 接下來我再看代碼就跳躍性的 畢竟我的目的是 QQ機器人 而不是 QQ的聊天協議 直接根據 myqq來改就好了 下面的代碼是myqq3中處理密碼的部分 感覺寫的還不錯 以後如果遇到命令行登錄的問題的時候 可以用這個來解決 註釋是原本就有的 另外改動了一小點代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    unsigned int pwi;
  char pswd;
  for(pwi=0;pwi<=32;pwi++)
  {
      pswd = getch(); //逐次赋值,但不回显 
      if(pswd == '\x0d')//回车则终止循环
      {
          password[pwi] ='\0';//getch需要补'\0'以适合原程序 
          break;
      }
      if(pswd == '\x08')//删除键则重输QQ密码 
      {
          if( pwi>0 ) pwi=-1;
          MSG(_TEXT("\n请重输QQ密码:"));
          continue;
      }
      printf("*"); //以星号代替字符
      password[pwi] =pswd;
  }

首先 總結下從這些代碼裡獲得的信息 「\x0d」代表的是 回車 「\x08」代表的是 刪除鍵 即 backspace 不過這個代碼有點不好的是 如果在輸入密碼的過程中 按到了 刪除鍵 則需要重新輸入密碼 而不能達到 只刪除一個字符的效果 不過 這也和 他輸入一個字符 printf一個星號有關係吧 至少我現在還不知道 如何在屏幕上 刪除一個已經輸出的字符 不過想想應該有辦法的吧 繼續說這個代碼 用戶輸入一個字符為一個循環 輸入的字符 依次賦password這個大數組裡 當輸入的為回車時證明輸入結束 在數組最後補上 「\0」表示結尾。

這篇先寫這麼多 後面還有很多的代碼要寫。。。 嗯

Comments