首页
社区
课程
招聘
idea源代码
发表于: 2005-1-30 10:41 6819

idea源代码

2005-1-30 10:41
6819
头文件
/* idea.h */

#ifndef _IDEA_DOT_H
#define _IDEA_DOT_H

#include <stdio.h>
#include <time.h>
#include <process.h>
#include <io.h>
#include <string.h>
#include <conio.h>

#define IDEAKEYSIZE 16
#define IDEABLOCKSIZE 8
#define word16 unsigned int
#define word32 unsigned long int
#define ROUNDS        8
#define KEYLEN        (6*ROUNDS+4)
#define tempfilename "tempfile.漕c"

int end_of_file,noisy,overwrite;   /*global vars*/

#define low16(x) ((x) & 0xffff)

typedef unsigned int uint16;
typedef word16 IDEAkey[KEYLEN];

/*IDEA Algorithm functions */
void en_key_idea(word16 userkey[8],IDEAkey Z);
void de_key_idea(IDEAkey Z, IDEAkey DK);
void cipher_idea(word16 in[4],word16 out[4],IDEAkey Z);
uint16 inv(uint16 x);
uint16 mul(uint16 a,uint16 b);

/*file handling functions*/
char read_char_from_file(FILE *fp);
word16 read_word16_from_file(FILE *fp);
void write_char_to_file(char data,FILE *fp);
void write_word16_to_file(word16 data,FILE *fp);
void cipher_file(FILE *in,FILE *out,word16 *key);
void decipher_file(FILE *in,FILE *out,word16 *key);
void swap_files_and_clean_up(char *file);

#endif

主程序

/*IDEA.C   v2.2
        c source code for IDEA block cipher. IDEA (International Data
        Encryption Algorithm), formerly known as IPES (Improved Proposed
        Encryption Standard). Algorithm developed by Xuejia Lai and James L.
        Massey, of ETH Zurich. This implementation modified and derived from
        original C code developed by Xuejia Lai. Zero-based indexing added,
        names changed from IPES to IDEA. CFB functions added. Random Number
        routines added. Optimized for speed 21 Oct 92 by Colin Plumb
        <colin@nsq.gts.org>  This code assumes that each pair of 8-bit bytes
        comprising a 16-bit word in the key and in the cipher block are
        externally represented with the Most Significant Byte (MSB) first,
        regardless of internal native byte order of the target cpu.
        modified for use with PC files by Colin Maroney 4/1/94*/

/*   USAGE:     pass a key made up of 8 16-bit numbers (word16) in an array
                ("word16 key[8];"), an input FILE * and an output temporary
                FILE * to either encode_file() or decode_file().
                where the key comes from is up to you.
                then call swap_files_and_clean_up() with the original file's
                name as the argument, to replace the original file
                with the encoded data (stored in the temporary file).

                you can remname the tempfile to be used in idea.h
                noisy is an integer which tells encrypting/decrypting
                functions to echo a "." every 256 writes, so the user can
                see that something is happening. set it to 0 for quiet
                running.

                please note that for really good security the original file
                is overwritten before being erased if you use the w switch.
                otherwise it outputs a file "<filename>.enc"

                the main() used here as illustration reads the filename
                from the command line arguments, as well as a command
                "e" or "d" to tell it whether to encrypt or
                decrypt, and a key.  the older versions had an interface
                for when a command line was not use.  lack of editing
                features made this buggy, so i axed it. */

#include "idea.h"

static uint16 inv(uint16 x)
{
   uint16 t0,t1;
   uint16 q,y;
   if (x<=1)
      return x;
   t1=(uint16)(0x10001l/x);
   y=(uint16)(0x10001l%x);
   if (y==1)
        return low16(1-t1);
   t0=1;
   do
   {
      q=x/y;
      x=x%y;
      t0+=q*t1;
      if (x==1)
        return t0;
      q=y/x;
      y=y%x;
      t1+=q*t0;
   } while (y!=1);
   return low16(1-t1);
}

static void en_key_idea(word16 *userkey, word16 *Z)
{
   int i,j;
   /* shifts */
   for (j=0;j<8;j++)
      Z[j]=*userkey++;
   for (i=0;j<KEYLEN;j++)
   {
      i++;
      Z[i+7]=((Z[i&7] << 9) | (Z[i+1 & 7] >> 7));
      Z+=i&8;
      i&=7;
   }
}

static void de_key_idea(IDEAkey Z,IDEAkey DK)
{
   int j;
   uint16 t1,t2,t3;
   IDEAkey T;
   word16 *p=T+KEYLEN;
   t1=inv(*Z++);
   t2=-*Z++;
   t3=-*Z++;
   *--p=inv(*Z++);
   *--p=t3;
   *--p=t2;
   *--p=t1;
   for (j=1;j<ROUNDS;j++)
   {
      t1=*Z++;
      *--p=*Z++;
      *--p=t1;
      t1=inv(*Z++);
      t2=-*Z++;
      t3=-*Z++;
      *--p=inv(*Z++);
      *--p=t2;
      *--p=t3;
      *--p=t1;
   }
   t1=*Z++;
   *--p=*Z++;
   *--p=t1;
   t1=inv(*Z++);
   t2=-*Z++;
   t3=-*Z++;
   *--p=inv(*Z++);
   *--p=t3;
   *--p=t2;
   *--p=t1;
   /*copy and destroy temp copy*/
   for(j=0,p=T;j<KEYLEN;j++)
   {
      *DK++=*p;
      *p++=0;
   }
}

uint16 mul(uint16 a, uint16 b)
{
   word32 p;

   if (a)
   {
      if (b)
      {
         p=(word32)a*b;
         b=(uint16)(low16(p));
         a=(uint16)(p>>16);
         return b-a+(b<a);
      }
      else
      {
         return 1-a;
      }
   }
   else
      return 1-b;
}

#define MUL(x,y) (x=mul(low16(x),y))

#define CONST

static void cipher_idea(word16 in[4],word16 out[4],register CONST IDEAkey Z)
{
   register uint16 x1,x2,x3,x4,t1,t2;
   int r=ROUNDS;
   x1=*in++; x2=*in++;
   x3=*in++; x4=*in;
   do
   {
      MUL(x1,*Z++);
      x2+=*Z++;
      x3+=*Z++;
      MUL(x4,*Z++);
      t2=x1^x3;
      MUL(t2,*Z++);
      t1=t2+(x2^x4);
      MUL(t1,*Z++);
      t2=t1+t2;
      x1^=t1;
      x4^=t2;
      t2^=x2;
      x2=x3^t1;
      x3=t2;
   } while (--r);
   MUL(x1,*Z++);
   *out++=x1;
   *out++=(x3+*Z++);
   *out++=(x2+*Z++);
   MUL(x4,*Z);
   *out=x4;
}

char read_char_from_file(FILE *fp)
{
   char temp=0;

   if ((fread(&temp,sizeof(char),1,fp))!=1)
      end_of_file=1;

   return (temp);
}

word16 read_word16_from_file(FILE *fp)
{
   word16 temp=0;

   if ((fread(&temp,sizeof(word16),1,fp))!=1)
      end_of_file=1;

   return temp;
}

void write_char_to_file(char data,FILE *fp)
{
   if ((fwrite(&data,sizeof(char),1,fp))!=1)
   {
      printf("Fatal Error writing output file!!!\n");
      exit(-1);
   }
}

void write_word16_to_file(word16 data,FILE *fp)
{
   if ((fwrite(&data,sizeof(word16),1,fp))!=1)
   {
      printf("Fatal Error writing output file!!!\n");
      exit(-1);
   }
}

void cipher_file(FILE *in,FILE *out,word16 *key)
{
   word16 input[4],output[4];
   IDEAkey Z;
   int x,y;
   int count=0;
   long length;
   int temp;

   en_key_idea(key,Z);
   end_of_file=0;

   length=filelength(fileno(in));
   fwrite(&length,sizeof(long),1,out);

   while (!end_of_file)
   {
      x=0;

      while (x<4)
      {
         input[x]=((word16)(read_char_from_file(in)<<8));
         if (!end_of_file)
         {
            temp=read_char_from_file(in);
            if (temp<0) temp+=256;
            input[x]=input[x]|temp;
            x++;
         }
         if (end_of_file)
         {
            while (x<4) input[x++]=0;
            break;
         }
      }

      cipher_idea(input,output,Z);

      for (y=0;y<x;y++)
      {
         if (noisy) if (count++%256==0) printf(".");
         write_word16_to_file(output[y],out);
      }
   }
}

void decipher_file(FILE *in,FILE *out,word16 *key)
{
   word16 input[4],output[4];
   int x,y;
   IDEAkey Z,DK;
   int count=0;
   long length=0;

   en_key_idea(key,Z);
   de_key_idea(Z,DK);

   end_of_file=0;

   fread(&length,sizeof(long),1,in);

   while (!end_of_file)
   {
      x=0;
      while (x<4)
      {
         input[x]=read_word16_from_file(in);
         if (end_of_file)
            break;
         x++;
      }
      cipher_idea(input,output,DK);
      for (y=0;y<x;y++)
      {
         if (noisy) if (count++%256==0) printf(".");
         if (length-->0)
            write_char_to_file(((char)(output[y]>>8)),out);
         if (length-->0)
            write_char_to_file(((char)(output[y]&255)),out);
      }
   }
}

void swap_files_and_clean_up(char *file)
{
   long fsize,count;
   FILE *fp;
   char temp[100];

   if (overwrite)
   {
      if ((fp=fopen(file,"r+b"))==NULL)
      {
         printf("\nError overwriting old file, security compromised.\n");
      }
      else
      {
         fseek(fp,0l,SEEK_END);
         fsize=ftell(fp);
         fseek(fp,0l,SEEK_SET);
         for (count=0;count<fsize;count++)
            fputc('0',fp);
         fclose(fp);
      }

      if ((remove(file))!=0)
      {
         printf("\nERROR removing old file <%s>\n",file);
         printf("encoded data remains in temporary file <%s>\n",tempfilename);
         exit(-1);
      }
   }
   else
   {
      strcpy(temp,file);
      file=strtok(temp,".");
      strcat(file,".enc");
   }

   if ((rename(tempfilename,file))!=0)
   {
      printf("\nERROR renaming temporary file <%s>!!\n",tempfilename);
      printf("Data is safely processed and stored in that file.\n");
      exit(-1);
   }
}

/*-----------------------------------------------*/

#define KBYTES 1024

void getuserkeyfromargv(word16 *key,char *arg)
{
   int x;

   for (x=0;x<strlen(arg) && x<8;x++)
   {
       if (x==0) key[x]=arg[x]<<8;
       else key[x]=((arg[x]<<8)|(key[x-1]>>8));
   }

   if (strlen(arg)>8) printf ("\nONLY first *8* characters of key used!!!\n");

   if (x<8) while (x<8) key[x++]=0;
}

main(int argc, char **argv)
{
   word16 userkey[8];
   char filename[100];
   FILE *fp,*temp;
   int to_or_from;

   noisy=1;
   overwrite=0;

   if (argc!=4)
   {
      printf("\nUsage: idea filename.ext [e|d[w]] key\n");
      printf("          e=encode   d=decode   w=overwrite file\n");
      printf("       NOTE: Key must be no longer than 8 characters long!!!\n");
      exit(-1);
   }
   else
   {
      strncpy(filename,argv[1],99);
      filename[99]='\0';
      if (argv[2][0]=='e') to_or_from=1;
      else if (argv[2][0]=='d') to_or_from=0;
      else
      {
         printf("\nUsage: idea filename.ext [e|d[w]] key\n");
         printf("                e=encrypt d=decrypt w=overwrite file\n");
         printf("       NOTE: Key must be no longer than 8 characters long!!!\n");
         exit(-1);
      }
      if (argv[2][1]=='w') overwrite=1;
      getuserkeyfromargv(userkey,argv[3]);
   }

   if ((fp=fopen(filename,"r+b"))==NULL)
   {
      printf("\nError opening File %s\n",filename);
      exit (-1);
   }

   if ((temp=fopen(tempfilename,"w+b"))==NULL)
   {
      printf("\nError opening temporary file\n");
      exit(-1);
   }

   if (to_or_from==1)
   {
      printf("\nEncoding file %s   ",filename);
      cipher_file(fp,temp,userkey);
   }
   else
   {
      printf("\nDecoding file %s   ",filename);
      decipher_file(fp,temp,userkey);
   }

   fclose (fp);
   fclose(temp);

   swap_files_and_clean_up(filename);

   return 0;
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 97697
活跃值: (200839)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
2
thinks!
2005-1-30 10:43
0
雪    币: 397
活跃值: (799)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wsy
3
上传附件失败,可能是文件格式不对
你复制下来用吧
不好意思,给你带来不便
2005-1-30 10:48
0
雪    币: 442
活跃值: (1216)
能力值: ( LV12,RANK:1130 )
在线值:
发帖
回帖
粉丝
4
Unit IDEA;

Interface
Uses
  Classes, Sysutils, DCPcrypt, DCPconst;

Type
  TDCP_idea = Class(TDCP_blockcipher)
  protected
    EK, DK: Array[0..51] Of word;
  public
    Class Function GetID: longint; override;
    Class Function GetAlgorithm: String; override;
    Class Function GetMaxKeySize: longint; override;
    Class Function GetBlockSize: longint; override;
    Class Function SelfTest: boolean; override;
    Procedure Init(Const Key; Size: longint; InitVector: pointer); override;
    Procedure Burn; override;
    Procedure EncryptECB(Const InData; Var OutData); override;
    Procedure DecryptECB(Const InData; Var OutData); override;
  End;

{******************************************************************************}
{******************************************************************************}
Implementation
{$R-}{$Q-}

Class Function TDCP_idea.GetMaxKeySize: longint;
Begin
  Result := 128;
End;

Class Function TDCP_idea.GetBlockSize: longint;
Begin
  Result := 64;
End;

Class Function TDCP_idea.GetID: longint;
Begin
  Result := DCP_idea;
End;

Class Function TDCP_idea.GetAlgorithm: String;
Begin
  Result := 'IDEA';
End;

Class Function TDCP_idea.SelfTest: boolean;
Const
  Key1: Array[0..15] Of byte =
  ($3A, $98, $4E, $20, $00, $19, $5D, $B3, $2E, $E5, $01, $C8, $C4, $7C, $EA, $60);
  InData1: Array[0..7] Of byte =
  ($01, $02, $03, $04, $05, $06, $07, $08);
  OutData1: Array[0..7] Of byte =
  ($97, $BC, $D8, $20, $07, $80, $DA, $86);
  Key2: Array[0..15] Of byte =
  ($00, $64, $00, $C8, $01, $2C, $01, $90, $01, $F4, $02, $58, $02, $BC, $03, $20);
  InData2: Array[0..7] Of byte =
  ($05, $32, $0A, $64, $14, $C8, $19, $FA);
  OutData2: Array[0..7] Of byte =
  ($65, $BE, $87, $E7, $A2, $53, $8A, $ED);
Var
  Cipher: TDCP_idea;
  Data: Array[0..7] Of byte;
Begin
  Cipher := TDCP_idea.Create(Nil);
  Cipher.Init(Key1, SizeOf(Key1) * 8, Nil);
  Cipher.EncryptECB(InData1, Data);
  Result := boolean(CompareMemory(@Data, @OutData1, SizeOf(Data)));
  Cipher.DecryptECB(Data, Data);
  Result := Result And boolean(CompareMemory(@Data, @InData1, SizeOf(Data)));
  Cipher.Burn;
  Cipher.Init(Key2, SizeOf(Key2) * 8, Nil);
  Cipher.EncryptECB(InData2, Data);
  Result := Result And boolean(CompareMemory(@Data, @OutData2, SizeOf(Data)));
  Cipher.DecryptECB(Data, Data);
  Result := Result And boolean(CompareMemory(@Data, @InData2, SizeOf(Data)));
  Cipher.Burn;
  Cipher.Free;
End;

Function MulInv(x: word): word;
Var
  t0, t1, q, y: word;
Begin
  If x <= 1 Then
  Begin
    Result := x;
    Exit;
  End;
  t1 := DWord($10001) Div x;
  y := DWord($10001) Mod x;
  If y = 1 Then
  Begin
    Result := (1 - t1) And $FFFF;
    Exit;
  End;
  t0 := 1;
  Repeat
    q := x Div y;
    x := x Mod y;
    t0 := t0 + (q * t1);
    If x = 1 Then
    Begin
      Result := t0;
      Exit;
    End;
    q := y Div x;
    y := y Mod x;
    t1 := t1 + (q * t0);
  Until y = 1;
  Result := (1 - t1) And $FFFF;
End;

Procedure TDCP_idea.Init(Const Key; Size: longint; InitVector: pointer);
Var
  i: integer;
Begin
  Inherited Init(Key, Size, InitVector);
  Size := Size Div 8;

  FillChar(EK, SizeOf(EK), 0);
  Move(Key, EK, Size);
  For i := 0 To 7 Do
    EK[i] := (EK[i] Shl 8) Or (EK[i] Shr 8);
  For i := 1 To 5 Do
  Begin
    EK[(i * 8) + 0] := (EK[((i - 1) * 8) + 1] Shl 9) Or (EK[((i - 1) * 8) + 2] Shr 7);
    EK[(i * 8) + 1] := (EK[((i - 1) * 8) + 2] Shl 9) Or (EK[((i - 1) * 8) + 3] Shr 7);
    EK[(i * 8) + 2] := (EK[((i - 1) * 8) + 3] Shl 9) Or (EK[((i - 1) * 8) + 4] Shr 7);
    EK[(i * 8) + 3] := (EK[((i - 1) * 8) + 4] Shl 9) Or (EK[((i - 1) * 8) + 5] Shr 7);
    EK[(i * 8) + 4] := (EK[((i - 1) * 8) + 5] Shl 9) Or (EK[((i - 1) * 8) + 6] Shr 7);
    EK[(i * 8) + 5] := (EK[((i - 1) * 8) + 6] Shl 9) Or (EK[((i - 1) * 8) + 7] Shr 7);
    EK[(i * 8) + 6] := (EK[((i - 1) * 8) + 7] Shl 9) Or (EK[((i - 1) * 8) + 0] Shr 7);
    EK[(i * 8) + 7] := (EK[((i - 1) * 8) + 0] Shl 9) Or (EK[((i - 1) * 8) + 1] Shr 7);
  End;
  EK[48] := (EK[41] Shl 9) Or (EK[42] Shr 7);
  EK[49] := (EK[42] Shl 9) Or (EK[43] Shr 7);
  EK[50] := (EK[43] Shl 9) Or (EK[44] Shr 7);
  EK[51] := (EK[44] Shl 9) Or (EK[45] Shr 7);

  DK[51] := MulInv(EK[3]);
  DK[50] := -EK[2];
  DK[49] := -EK[1];
  DK[48] := MulInv(EK[0]);
  For i := 0 To 6 Do
  Begin
    DK[47 - i * 6] := EK[i * 6 + 5];
    DK[46 - i * 6] := EK[i * 6 + 4];
    DK[45 - i * 6] := MulInv(EK[i * 6 + 9]);
    DK[44 - i * 6] := -EK[i * 6 + 7];
    DK[43 - i * 6] := -EK[i * 6 + 8];
    DK[42 - i * 6] := MulInv(EK[i * 6 + 6]);
  End;
  DK[5] := EK[47];
  DK[4] := EK[46];
  DK[3] := MulInv(EK[51]);
  DK[2] := -EK[50];
  DK[1] := -EK[49];
  DK[0] := MulInv(EK[48]);

  { Generate a "random" IV }
  If InitVector = Nil Then
  Begin
    FillChar(IV^, BS, 0);
    EncryptECB(IV^, IV^);
    Reset;
  End
  Else
  Begin
    Move(InitVector^, IV^, BS);
    Reset;
  End;
End;

Procedure TDCP_idea.Burn;
Begin
  FillChar(EK, SizeOf(EK), 0);
  FillChar(DK, SizeOf(DK), 0);
  Inherited Burn;
End;

Procedure Mul(Var x: word; Const y: word);
Var
  p: DWord;
  t16: word;
Begin
  p := DWord(x) * y;
  If p = 0 Then
    x := 1 - x - y
  Else
  Begin
    x := p Shr 16;
    t16 := p And $FFFF;
    x := t16 - x;
    If (t16 < x) Then
      Inc(x);
  End;
End;

Procedure TDCP_idea.EncryptECB(Const InData; Var OutData);
Var
  x: Array[1..4] Of word;
  s3, s2: word;
  i: longint;
Begin
  If Not fInitialized Then
    Raise EDCP_blockcipher.Create('Cipher not initialized');
  PDword(@x[1])^ := PDword(@InData)^;
  PDword(@x[3])^ := PDword(DWord(@InData) + 4)^;
  For i := 1 To 4 Do
    x[i] := (x[i] Shl 8) Or (x[i] Shr 8);
  For i := 0 To 7 Do
  Begin
    Mul(x[1], EK[(i * 6) + 0]);
    Inc(x[2], EK[(i * 6) + 1]);
    Inc(x[3], EK[(i * 6) + 2]);
    Mul(x[4], EK[(i * 6) + 3]);
    s3 := x[3];
    x[3] := x[3] Xor x[1];
    Mul(x[3], EK[(i * 6) + 4]);
    s2 := x[2];
    x[2] := x[2] Xor x[4];
    Inc(x[2], x[3]);
    Mul(x[2], EK[(i * 6) + 5]);
    Inc(x[3], x[2]);
    x[1] := x[1] Xor x[2];
    x[4] := x[4] Xor x[3];
    x[2] := x[2] Xor s3;
    x[3] := x[3] Xor s2;
  End;
  Mul(x[1], EK[48]);
  Inc(x[3], EK[49]);
  Inc(x[2], EK[50]);
  Mul(x[4], EK[51]);
  x[1] := (x[1] Shl 8) Or (x[1] Shr 8);
  s2 := (x[3] Shl 8) Or (x[3] Shr 8);
  x[3] := (x[2] Shl 8) Or (x[2] Shr 8);
  x[4] := (x[4] Shl 8) Or (x[4] Shr 8);
  x[2] := s2;
  PDword(@OutData)^ := PDword(@x[1])^;
  PDword(DWord(@OutData) + 4)^ := PDword(@x[3])^;
End;

Procedure TDCP_idea.DecryptECB(Const InData; Var OutData);
Var
  x: Array[1..4] Of word;
  s3, s2: word;
  i: longint;
Begin
  If Not fInitialized Then
    Raise EDCP_blockcipher.Create('Cipher not initialized');
  PDword(@x[1])^ := PDword(@InData)^;
  PDword(@x[3])^ := PDword(DWord(@InData) + 4)^;
  For i := 1 To 4 Do
    x[i] := (x[i] Shl 8) Or (x[i] Shr 8);
  For i := 0 To 7 Do
  Begin
    Mul(x[1], DK[(i * 6) + 0]);
    Inc(x[2], DK[(i * 6) + 1]);
    Inc(x[3], DK[(i * 6) + 2]);
    Mul(x[4], DK[(i * 6) + 3]);
    s3 := x[3];
    x[3] := x[3] Xor x[1];
    Mul(x[3], DK[(i * 6) + 4]);
    s2 := x[2];
    x[2] := x[2] Xor x[4];
    Inc(x[2], x[3]);
    Mul(x[2], DK[(i * 6) + 5]);
    Inc(x[3], x[2]);
    x[1] := x[1] Xor x[2];
    x[4] := x[4] Xor x[3];
    x[2] := x[2] Xor s3;
    x[3] := x[3] Xor s2;
  End;
  Mul(x[1], DK[48]);
  Inc(x[3], DK[49]);
  Inc(x[2], DK[50]);
  Mul(x[4], DK[51]);
  x[1] := (x[1] Shl 8) Or (x[1] Shr 8);
  s2 := (x[3] Shl 8) Or (x[3] Shr 8);
  x[3] := (x[2] Shl 8) Or (x[2] Shr 8);
  x[4] := (x[4] Shl 8) Or (x[4] Shr 8);
  x[2] := s2;
  PDword(@OutData)^ := PDword(@x[1])^;
  PDword(DWord(@OutData) + 4)^ := PDword(@x[3])^;
End;

Initialization
  RegisterClass(TDCP_idea);
  DCPregcipher(TDCP_idea, true);

End.
2005-1-30 10:56
0
雪    币: 397
活跃值: (799)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wsy
5
你自己也找到了,那应该没问题了吧。
祝你成功
2005-1-30 11:04
0
雪    币: 442
活跃值: (1216)
能力值: ( LV12,RANK:1130 )
在线值:
发帖
回帖
粉丝
6
多谢老大,感谢答公无私的帮助!
2005-1-30 11:07
0
雪    币: 397
活跃值: (799)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wsy
7
这是我应该做的
也是我的乐趣所在
2005-1-30 11:23
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
rt
2005-1-30 18:00
0
游客
登录 | 注册 方可回帖
返回
//