Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Проблемка с кодом


Автор: proman 13.5.2006, 09:17
привет! 
Вобщем проблема такая: мне надо кодировать и декодировать фаил в формат Base64 
грубо говоря схема такая: 
"деление три к четырем" из трех бай делаем 4 по 6 Бит 
Кароче из файла читаем по 57 байт и каждые 57 байт переводим в строку по 76 символов. 
Тут всё работает только не понятно там где между звездочек выделено. 
HANDLE FileData; 
DWORD nReadBytes; 
const char base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 


long base64encode(const char* FileName, char* buffer,unsigned  int length) 
{ 
   //Я сделал чтение из файла по 57 байт, чтоб не сильно переиначивать функшу по сравнению с uu- кодированием. 
   unsigned char ReadData[57];//исходная строка 
   unsigned char ResData[76];//закодированная строка 
   unsigned long p=0; 
   unsigned long len=0;       unsigned long SourceLen=0;//длина исходного файла. 
   unsigned long CurResBufferPos=0;//с этой позиции в результирующий буфер заноситься очередная закодированная строка 
   unsigned int j; 
   unsigned char tmpchar; 
  FileData=CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); 
   if(FileData==INVALID_HANDLE_VALUE) return 0; 
      do 
   { 
       memset(ReadData,0,57);//заполняем все нулями, для того, чобы если в строке *** будет попытка 
      //залезть за nReadBytes, такое возможно, тк i уведичивается каждый раз на 3, 
      //то лишние байты не будут содержать мусора, а нули не испортят нужные данные 
       ReadFile(FileData,ReadData,57,&nReadBytes,NULL);//прочитали строку 45 байт 
       if (nReadBytes==0) 
       { 
           CloseHandle(FileData); 
           return len;//на тот случай, если размер файла кратен 57. иначе бы мы читали 0 байт, И ЭТОТ НОЛЬ ШЕЛ БЫ ТОЖЕ В ОТСЛЫКУ. 
       } 
       //если же размер файла кратен 57, то он кратен 3, следовательно в коенц закодированного собщение не нужно добавлять знаки равенства. 
              //закодируем ее. 
       j=0; 
       SourceLen+=nReadBytes;// тут мы подсчитываем размер исходного файла. 




********************************************************************
*Вот тут(всё что между звездочек) всё чето глухо некак не пойму понятно что берём по 3 байта в начале а дальше ниче не понятно 
* 
*        for(unsigned int i=0;i<nReadBytes;i+=3)//кодируем по три байта 
       { 
           p=ReadData[i+2]+ReadData[i+1]*256+ReadData[i]*65536;//Тут не ясно зачем умножать на 256 и на 65536 и чемуже будет равно р 
           for(unsigned char i1=0;i1<3;i1++) //Этот цикл вабще не понимаю че делает 
           { 
               tmpchar=p; 
               tmpchar<<=2;//что нам дает этот сдвиг 
               tmpchar>>=2;//что нам дает этот сдвиг 
               ResData[j+3-i1]=tmpchar; 
               p>>=6;//сдвигаем на  6 бит Зачем ? 
           } 
           ResData[j]=p;//в p остались только послдение 6 бит. Их и занесем в результирующую строку. 
           j+=4; //А тут незнаю почему увелич на 4 
Пробовал делать Трасировку не помогло. 
       }* 
*********************************************************************************************





       len+=j+1;//j - сколько байтов в ResData, плюс один байт - конец строки 
              //теперь закодированную строку нужно занести в результирующий буффер 
       if(len<=length)//если есть место в буффере 
       { 
           for(unsigned char i1=0;i1<j;i1++)//нужно перенести j символов 
           { 
               buffer[CurResBufferPos+i1]=base64[ResData[i1]];//-1 тк в uucode нумерация начинается с нуля 
           } 
                      buffer[CurResBufferPos+j]='\n'; 
           CurResBufferPos+=j+1; 
       } 
       else return 0; 
       
   } 
   while(nReadBytes==57); 

   //теперь если размер исходного файла дает при делении на 3 остаток 1, то нужно замениь два последних символа ( а это будут нули) на знаки = 
   //если размер исходного файла дает при делении на 3 остаток 2, то нужно аменить последний символ знаком =. 
   char pad=(3-SourceLen%3)%3;//подсчитываем, сколько знаков = нужно ставить. столь хитрая формула действительно действует, возвращая 0 знаков =, если размер файла кратен 3. 
   while(pad>0) 
   { 
       buffer[CurResBufferPos-1-pad]='=';//последний символ в buffer это '\n', его не нужно менять. меняем символы перед ним. 
       pad--; 
   } 
   CloseHandle(FileData); 
   return len; 
}
 

Автор: GrayCardinal 13.5.2006, 10:44
И куда смотрят модераторы, а ? Перенесите тему плиз, а то мне от "CreateFile" плохо становится. 

Автор: proman 15.5.2006, 14:58
Я не про CreateFile спрашываю а про часть кода которая между звездочками не знаешь че там такое так и скажи незнаю! А то что тебе плохо или хорошо становится от того че ты увидел  я думаю тут большенству по ! 

Автор: Spalax 16.5.2006, 08:07
А ты попробуй продебажить и посмотри что куда ..... 
ну а во вторых насколько я знаю в етом форуме обсуждаються вопросы касающиеся программирования под UNIX.
А вот ето 
Код

HANDLE FileData; 
DWORD nReadBytes;

насколько я знаю стиль написания Мелко мягких ну а во вторых мой тебе совет перепиши етот код а то он тупо Виндовый я думаю в std библиотеке найдуться замены ну наподлобии вместьо CreateFile написать там fopen("file_name","w+");
Так что ты подумай 

Автор: proman 16.5.2006, 13:24
Да я уже все переписал все работает мне разобраться надо только в этом:
Код

Вот тут(всё что между звездочек) всё чето глухо некак не пойму понятно что берём по 3 байта в начале а дальше ниче не понятно 
* 
*        for(unsigned int i=0;i<nReadBytes;i+=3)//кодируем по три байта 
       { 
           p=ReadData[i+2]+ReadData[i+1]*256+ReadData[i]*65536;//Тут не ясно зачем умножать на 256 и на 65536 и чемуже будет равно р 
           for(unsigned char i1=0;i1<3;i1++) //Этот цикл вабще не понимаю че делает 
           { 
               tmpchar=p; 
               tmpchar<<=2;//что нам дает этот сдвиг 
               tmpchar>>=2;//что нам дает этот сдвиг 
               ResData[j+3-i1]=tmpchar; 
               p>>=6;//сдвигаем на  6 бит Зачем ? 
           } 
           ResData[j]=p;//в p остались только послдение 6 бит. Их и занесем в результирующую строку. 
           j+=4; //А тут незнаю почему увелич на 4 
Пробовал делать Трасировку не помогло. 
       }* 
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)