отправлял картинку на стену, решил проснифать запрос. Увидел нечто такое: в контенте страниц я ничего ненашел.. где ж его искать то? о_О
Для снифа заюзай CommView и не парься. Когда всё сделаешь, то поищи в тексте слово signature и выдери из него значение. Затем поищи в тексте это значение. так и найдеш кто и когда его поставил
Этот хеш берется из флешки в которой рисуют граффити. После декомпиляции я понял как он генерируется, а именно : 1. Весь PNG файл конвертируется в base64 2. Из получееных данных берется первые 1024 байт и из них создаётся MD5 хэш, который собсна вы и видите. З.Ы. Из инета не берите кодер base64, во флешке он специфичный немного.
при попытке отослать картинку, возникает ошибка: HTTP/1.1 413 Request Entity Too Large исользован следующий код: Code: // ---- Отправка картинки на стену ---- procedure TidVKClient.PostWallPicture(const to_id, AFile: string); var Multi : TIdMultiPartFormDataStream; Signature : string; URL : string; begin Multi := TIdMultiPartFormDataStream.Create; Signature := StrTobase64(file_get_contents(AFile), 0); Signature := Copy(Signature, 0, 1024); ShowMessage(IntToStr(Length(Signature))); Signature := GetMD5(Signature); url := 'http://vkontakte.ru/graffiti.php?to_id=' + to_id + '&group_id=0'; Multi.AddFormField('Signature', Signature); Multi.AddFile('Filedata', AFile, 'image/png'); HTTP.Post(url, multi); end;
У меня не получилось отослать граффити, мне выдает 400/ Bad Request, что означает что контакт понял что не флешка граффити отправляет. Короче, вот что я накалякал после декомпилирования флешки и портирования(с некоторым изменением на делфи), работает 100% Code: unit EncryptsUnit; interface Uses Windows, SysUtils; type TByteArray = array of Byte; function base64_encodeByteArray(data : TByteArray) : String; function base64_decodeToByteArray(data : String) : TByteArray; function base64_encode(inStr : String) : String; function base64_decode(inStr : String) : String; implementation {---------------------------------------------------------------} {--BASE64 Encode, Decode----------------------------------------} {---------------------------------------------------------------} const version : String = '1.0.0'; BASE64_CHARS : String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; function BASE64_Index(c : Char) : Byte; Var ci : Byte; Begin ci := Ord(c); if ci <= $3D then Begin if (ci <= $39) then Begin if (ci >= $30) then Result := 53 + (ci - $30) else Begin if ci = $2B then Result := 63 else if ci = $2F then Result := 64; end; end else Result := 65; Exit; end; if ci <= $5A then Begin Result := ci - $40; Exit; end; if ci <= $7A then Begin Result := 26 + ci - $60; Exit; end; Result := 65; end; function base64_encode(inStr : String) : String; Var ba : TByteArray; utf : String; Begin utf := AnsiToUtf8(inStr); SetLength(ba, Length(utf)); Move(utf[1], ba[0], Length(utf)); Result := base64_encodeByteArray(ba); end; function base64_encodeByteArray(data : TByteArray) : String; Var inBuf : Array of Byte; i, j, k : Cardinal; outBuf : array[0..3] of Byte; dataPos : Cardinal; Begin dataPos := 0; Result := ''; i := 0; while (dataPos <= High(data)) do Begin SetLength(inBuf, 3); FillChar(inBuf[0], 3, 0); i := 0; while ((i < 3) and (dataPos <= High(data))) do Begin inBuf[i] := data[dataPos]; i := i + 1; Inc(dataPos); end; outBuf[0] := (inBuf[0] and 252) shr 2; outBuf[1] := ((inBuf[0] and 3) shl 4) or (inBuf[1] shr 4); outBuf[2] := ((inBuf[1] and 15) shl 2) or (inBuf[2] shr 6); outBuf[3] := inBuf[2] and 63; while (i < 3) do Begin outBuf[(i + 1)] := 64; i := i + 1; end; k := 0; while (k < 4) do Begin Result := Result + BASE64_CHARS[outBuf[k]+1]; k := k + 1; end; end; end; function base64_decode (inStr : String) : String; Var ba : TByteArray; utf : String; Begin ba := base64_decodeToByteArray(inStr); SetLength(utf, High(ba)+1); Move(ba[0], utf[1], High(ba)+1); Result := System.Utf8ToAnsi(utf); end; function base64_decodeToByteArray(data : String) : TByteArray; Var i, j, k : Cardinal; inBuf : Array[0..3] of Byte; outBuf : Array[0..2] of Byte; _HypArray : TByteArray; _HypLength : Cardinal; const ReAlignStep = 1024*1024*2; {Эт для того что бы менеджер память по байту не насиловать} Begin i := 0; _HypLength := 0; SetLength(_HypArray, ReAlignStep); while (i < Length(data)) do Begin j := 0; while ((j < 4) and (i + j < Length(data))) do Begin inBuf[j] := BASE64_Index(data[i + j + 1]) - 1; Inc(j); end; outBuf[0] := (inBuf[0] shl 2) + ((inBuf[1] and 48) shr 4); outBuf[1] := ((inBuf[1] and 15) shl 4) + ((inBuf[2] and 60) shr 2); outBuf[2] := ((inBuf[2] and 3) shl 6) + inBuf[3]; k := 0; while (k < 3) do Begin if (inBuf[(k + 1)] = 64) then Break; _HypArray[_HypLength] := outBuf[k]; Inc(_HypLength); if _HypLength > High(_HypArray) then SetLength(_HypArray, High(_HypArray)+ReAlignStep+1); Inc(k); end; Inc(i, 4); end; SetLength(Result, _HypLength); Move(_HypArray[0], Result[0], _HypLength); end; end. Модуль MD5 берется стандартный. А вот над TIdMultiPartFormDataStream придётся немного пошаманить(когда след. код разбрешь - поймёшь что). Вот код отправки(понять можно) Code: SetLength(signature, wallMem.Size); Move(PByte(wallMem.Memory)^, signature[1], wallMem.Size); signature := base64_encode(signature); SetLength(signature, Min(1024, Length(signature))); signature := StrMD5(signature); {Заполняем поля в запрос} wallPost := TIdMultiPartFormDataStream.Create; wallPost.Boundary := '--OLEG-ANDREEV-PAVEL-DUROV-GRAFFITI-POST'; wallPost.RequestContentType := sContentType + wallPost.Boundary; wallPost.AddFormField('Signature', LowerCase(signature)); Exit; wallPost.AddObject('Filedata', 'image/png', wallMem, 'graffiti.png'); wallPost.AddFormField('Upload', 'Submit Query'); {дальше отправка wallPost} Примечание - в wallMem : TMemoryStream хранится весь PNG файл. Есть ещё трабла с TIdMultiPartFormDataStream в том что флешка немного не так завершает POST данные и это единственное различие, осталось только его переписать и тогда граффити отправится(один раз кстати у меня получилось отправить но потом контакт выдал System Error, что меня немного напугало и я опыты оставил).
Кстати в нижнем коде в одном месте Exit стоит, его надо проигнорировать естественно, я его для отладки вставлял) А верхний код кривоват, т.к. не полностью оптимизировал текст после декомпиляции.
Блин нашёл почему граффити не отправляется, у них тоже переделаный немного MD5, вот придётся весь модуль декомпилировать и портировать. Если удастся, выложу сюда.
Модули base64 и md5 брал из проги vkontakte picture. Щас все работает даже не надо нажимать кнопку отправить на странице, компонент сам парсит все запросы.