пятница, 11 января 2013 г.

Как я ебался с diff'ами

Diff из пакета mingw и winmerge не умеют делать разницу между двумя Exe.

В то же время WinRar делает solid архивы, учитывающие различия в двух почти одинаковых исполнимых файлах.

На карте rar файла мы имеем [Application1.Exe][Application2.Exe], если в Hiew убрать из rar первое приложение, то останется отличие второго от первого.

Microsoft давно что-то типа этого придумала, но для меня это в новинку.

Можно долго описывать какая лажа winmerge, не качайте это говно!

Отличия я делал для своей программы PrintWisdom, версии 2.20 и 2.21.

PrintWisdom.Exe версии 2.20 занимает 690k, diff получился 77k.

Вся фигня с diff'ами придумалась, когда на балансе 3G интернета остались деньги, но время тарифного плана истекло, т.е. можно было послать по почте что-то очень маленькое.

Hiew это замечательно, но как восстановить Application2.Exe из Diff'а? Это же не полноценный rar архив, а только его остаток?

Вручную я это сделал достаточно быстро, только небольшая ломка пока придумал как.

Затем долго исправлял программу на Си, делающую то же самое. Я пожалуй вставлю её ниже.

#include
#include
#include
#include

int myfind(FILE *f, char *s)
{
const int BUF_SIZE = 1;
char b[BUF_SIZE];
int pos = -1;
int L = strlen(s);
int fptr;
while (true)
{
int n = 0;
int matches = 0;
fptr = ftell(f);
LOOP:
fread(b, BUF_SIZE, 1, f);
if (ferror(f)) break;
if (b[0] == s[n])
{
matches++;
if (matches == L)
return fptr;
if (matches < L)
{
n++;
goto LOOP;
}
}
}
return pos;
}

int main()
{
system("copy PrintWisdom.1 PrintWisdom.2");
FILE *file1 = fopen("PrintWisdom.2", "r+b");
int random_position = 0x963;
char random_byte = 0x51;
fseek(file1, random_position, 0);
fwrite(&random_byte, 1, 1, file1);
fclose(file1);
// WinRAR should be V4.1.0!
system("\"C:\\Program Files\\WinRAR\\WinRAR.exe\" a -m5 -s PrintWisdom.rar PrintWisdom.1 PrintWisdom.2");
FILE *file2 = fopen("PrintWisdom.rar", "r+b");
int pos = myfind(file2, "PrintWisdom.2");
fseek(file2, pos-50, 0);
chsize(file2->fd, ftell(file2));
fclose(file2);
system("copy /b PrintWisdom.rar + PrintWisdom.diff my.rar");
system("rar t my.rar");
return EXIT_SUCCESS;
}

Подразумевается, что файл PrintWisdom.1 (переименованный PrintWisdom.Exe версии 2.20) у получателя почты есть.

Функция myfind ищет строку в двоичном файле, как F7 в Hiew. Используются нестандартные возможности среды Си, например chsize.

вторник, 8 января 2013 г.

Типа перестройка личности, а зубы не заметили

На днях возникло подозрение (навеяно), что не все матрицы в кейсе читаются.

Программа CDRoller сдирает матрицы в ISO образ, забивая ошибочные секторы нулями. Не ахти разумное поведение, но я остановился именно на CDRoller.

Из всей кипы матриц в бумажных конвертиках я выбрал 12, процесс риппинга большей частью прерывался на 99%, дальше типа нули на карте ISO образа.

Содрать в ISO (получилось 12 образов) и сделать простой rar - это полдела.

Появилось простое желание купить для хранения этого rar карточку micro sd.

Rar примерно 7.5, карточка соответственно была нужна на 8.

Короче купил, вставил наугад в свой USB модем (со второй попытки) и записал rar на карточку.

четверг, 3 января 2013 г.

Print Wisdom V2.20 "Ball Pen"

//---------------------------------------------------------------------------

#include
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

#define W_COUNT 19780
#define MAX_RANGES 20
#define MAX_PRESETS 6
#define DEFAULT_PRESET 1
#define FOLDER_ICONS "icons\\"
#define FOLDER_PHOTO1 "Photo1\\"
#define FOLDER_PHOTO2 "Photo2\\"
using namespace std;

struct range {
int a, b;
};

AnsiString PresetID[MAX_PRESETS] = {
"Level 1",
"Level 2",
"Level 3",
"Level 4",
"Level 5",
"Level 6"
};

int Presets[MAX_PRESETS][MAX_RANGES] = {
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1},
{1,1,1,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,1},
{1,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,1},
{0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};

string RANGE_ID[MAX_RANGES] = {
"My questions",
"Rainbow core",
"Google core",
"Science fiction library",
"Wide screen photo 1",
"Wide screen photo 2",
"Ballads",
"My music",
"Wisdoms",
"Thoughts",
"Blog themes",
"My dreams",
"Alternative blog themes",
"Top 1000",
"Films 1",
"Films 2",
"Actors",
"Russian picture set",
"Fifty fifty",
"Spy library"
};

char *SoundFiles[MAX_RANGES] = {
"My questions.wav",
"Rainbow core.wav",
"Google core.wav",
"Science fiction library.wav",
"Wide screen photo 1.wav",
"Wide screen photo 2.wav",
"Ballads.wav",
"My music.wav",
"Wisdoms.wav",
"Thoughts.wav",
"Blog themes.wav",
"My dreams.wav",
"Alternative blog themes.wav",
"Top 1000.wav",
"Films 1.wav",
"Films 2.wav",
"Actors.wav",
"Russian picture set.wav",
"Fifty fifty.wav",
"Spy library.wav"
};

// !345, !1444, !595, !2303, !252, !444,
// !180, !153, !1179, !35, !809, !36, !225, !1000,
// !1340, !1075, !6846, !603, !586, !330

int capacity[MAX_RANGES] = {
345,1444,595,2303,252,444,180,153,1179,35,
809,36,225,1000,1340,1075,6846,603,586,330
};

range ranges[MAX_RANGES] = {
{0,344},
{345,1788},
{1789,2383},
{2384,4686},
{4687,4938},
{4939,5382},
{5383,5562},
{5563,5715},
{5716,6894},
{6895,6929},
{6930,7738},
{7739,7774},
{7775,7999},
{8000,8999},
{9000,10339},
{10340,11414},
{11415,18260},
{18261,18863},
{18864,19449},
{19450,19779}
};

void TForm1::ActivatePreset(int n)
{
CheckBox1->Checked = (bool)Presets[n][0];
CheckBox2->Checked = (bool)Presets[n][1];
CheckBox3->Checked = (bool)Presets[n][2];
CheckBox4->Checked = (bool)Presets[n][3];
CheckBox5->Checked = (bool)Presets[n][4];
CheckBox6->Checked = (bool)Presets[n][5];
CheckBox7->Checked = (bool)Presets[n][6];
CheckBox8->Checked = (bool)Presets[n][7];
CheckBox9->Checked = (bool)Presets[n][8];
CheckBox10->Checked = (bool)Presets[n][9];
CheckBox11->Checked = (bool)Presets[n][10];
CheckBox12->Checked = (bool)Presets[n][11];
CheckBox13->Checked = (bool)Presets[n][12];
CheckBox14->Checked = (bool)Presets[n][13];
CheckBox15->Checked = (bool)Presets[n][14];
CheckBox16->Checked = (bool)Presets[n][15];
CheckBox17->Checked = (bool)Presets[n][16];
CheckBox18->Checked = (bool)Presets[n][17];
CheckBox19->Checked = (bool)Presets[n][18];
CheckBox20->Checked = (bool)Presets[n][19];
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Edit1->SelectAll();
Edit1->ClearSelection();

for (int n=0; n < MAX_PRESETS; n++)
{
TObject *foo = new TObject;
ComboBox1->AddItem(PresetID[n],foo);
}

ComboBox1->SelStart = 0;
ComboBox1->SelLength = 9;
ComboBox1->SelText = PresetID[DEFAULT_PRESET];

ActivatePreset(DEFAULT_PRESET);

CurRow = 1;
StringGrid1->ColCount = 2;
StringGrid1->ColWidths[1] = 400;
StringGrid1->RowCount = 16384;
StringGrid1->DefaultRowHeight = 16;

Button2->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
randomx r(time(NULL));
FILE *W = fopen("Wisdom.dat", "rt");
vector Wisdoms;
for (int n=0; n < W_COUNT; n++)
{
char s[8192];
fgets(s, sizeof s, W);
do {
if (s[strlen(s)-1] == 0x0D || s[strlen(s)-1] == 0x0A)
s[strlen(s)-1] = 0;
else break;
} while (true);
Wisdoms.push_back(string(s));
}
fclose(W);

vector Opt;

Opt.push_back(CheckBox1->Checked);
Opt.push_back(CheckBox2->Checked);
Opt.push_back(CheckBox3->Checked);
Opt.push_back(CheckBox4->Checked);
Opt.push_back(CheckBox5->Checked);
Opt.push_back(CheckBox6->Checked);
Opt.push_back(CheckBox7->Checked);
Opt.push_back(CheckBox8->Checked);
Opt.push_back(CheckBox9->Checked);
Opt.push_back(CheckBox10->Checked);
Opt.push_back(CheckBox11->Checked);
Opt.push_back(CheckBox12->Checked);
Opt.push_back(CheckBox13->Checked);
Opt.push_back(CheckBox14->Checked);
Opt.push_back(CheckBox15->Checked);
Opt.push_back(CheckBox16->Checked);
Opt.push_back(CheckBox17->Checked);
Opt.push_back(CheckBox18->Checked);
Opt.push_back(CheckBox19->Checked);
Opt.push_back(CheckBox20->Checked);

Edit1->SelectAll();
Edit1->ClearSelection();

static vector pool[MAX_RANGES];
int ind = 0;
int RANGE_NUM = 0;
int N = 0;

CREATE_INDEX:
ind = 0;
RANGE_NUM = 0;

while (true)
{
ind = r.rand_n(W_COUNT);
for (int R=0; R < MAX_RANGES; R++)
{
if (ind >= ranges[R].a && ind <= ranges[R].b)
{
RANGE_NUM = R;
break;
}
}
if (Opt[RANGE_NUM]) break;
}

if (CheckBox21->Checked)
{
if (pool[RANGE_NUM].size() == capacity[RANGE_NUM])
pool[RANGE_NUM].clear();
if (pool[RANGE_NUM].size() == 0)
pool[RANGE_NUM].push_back(ind);
else {
for (N=0; N < pool[RANGE_NUM].size(); N++)
if (pool[RANGE_NUM][N] == ind)
goto CREATE_INDEX;
pool[RANGE_NUM].push_back(ind);
}

}

static char buf[8192];
strcpy(buf, Wisdoms[ind].c_str());
Edit1->SetSelTextBuf(buf);

if (RANGE_NUM==2 || RANGE_NUM==4 || RANGE_NUM==5)
{
TJPEGImage *GraphicsFile = new TJPEGImage();
string gFile = buf;
gFile += ".jpg";
switch (RANGE_NUM) {
case 2: gFile = FOLDER_ICONS + gFile;break;
case 4: gFile = FOLDER_PHOTO1 + gFile;break;
case 5: gFile = FOLDER_PHOTO2 + gFile;break;
}
GraphicsFile->LoadFromFile(AnsiString(gFile.c_str()));
Word AFormat;
unsigned AData;
HPALETTE APalette;
GraphicsFile->SaveToClipboardFormat(AFormat,AData,APalette);
TPicture *Bitmap = new TPicture();
Bitmap->LoadFromClipboardFormat(AFormat, AData, APalette);
Image1->Picture = Bitmap;
delete Bitmap;
delete GraphicsFile;
} else {
TPicture *Bitmap = new TPicture();
Image1->Picture = Bitmap;
delete Bitmap;
}

StringGrid1->Cells[1][CurRow++] = AnsiString(buf);
if (CurRow==2) {
StringGrid1->TopRow = CurRow-1;
Button2->Enabled = true;
}
else if (CurRow==3) StringGrid1->TopRow = CurRow-2;
else if (CurRow==4) StringGrid1->TopRow = CurRow-3;
else if (CurRow==5) StringGrid1->TopRow = CurRow-4;
else if (CurRow==6) StringGrid1->TopRow = CurRow-5;
else StringGrid1->TopRow = CurRow-6;
StringGrid1->EditorMode = true;

sndPlaySound(SoundFiles[RANGE_NUM], SND_SYNC);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
ComboBox1->SelStart = 0;
ComboBox1->SelLength = 7;

int ID = 0;
for (int n=0; n < MAX_PRESETS; n++)
if (ComboBox1->SelText == PresetID[n])
{
ID = n;
break;
}

ActivatePreset(ID);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
FILE *T = fopen("Table.txt", "wt");
for (int n=1; n < CurRow; n++)
fputs((StringGrid1->Cells[1][n]+"\n").c_str(), T);
fclose(T);
Application->MessageBox("File saved successfully!", "Message", MB_OK);
}
//---------------------------------------------------------------------------