Mini fake kompilator - Zamiana OEM\ASCII na BIN.

0

Witam, chciałbym zrobić taki mały kompilator, oczywiście nie kompilowałby na serio, tylko tłumaczyłby tekst OEM(kodowanie używane w DOS) na BIN(binarny, dwójkowy), oraz "wychaczałby" pewne linijki np.:
URUCHOM "program.exe"
I zamieniałby jeszcze przed "kompilacją" na:
URUCHOM "inny_program.exe" "program.exe"
Oczywiście program musiałby działać w dwie strony, tzn. kod też powinien umieć z powrotem przetłumaczyć na OEM.

Program będzie mi służyć do tłumaczenia różnych skryptów(np. Batch, VBS, itp.) aby były nieczytelne, ale abym mógł je szybko przetłumaczyć z powrotem i uruchomić.

P.S. Jeśli OEM jest jakimś problemem to ASCII będzie mi musiał wystarczyć...

Z góry dziękuję, bo wiem że mi pomożecie jak zawsze :)

0

Dużo nie zmieniasz - szyfr grosenfielda by ci tutaj styknął - robi ładne, nieczytelne szlaczki, a całość da się odkodować tylko z kluczem.

0

Nie wiem, ale zależy mi jakoś na BIN.

A nie wie ktoś może jak zrobić aby program wyłuskiwał kawał kody i zamieniał go na inny? Np. Linijka
URUCHOM "program.exe"

Zamieniana by była jeszcze przed "kompilacją" na:
URUCHOM "inny_program.exe"

Nie mam bladego pojęcia, od czego zacząć...

0

Line=StringReplace(Line,'URUCHOM "','URUCHOM "inny_',[rfReplaceAll]);

function ToBin(const Line:String):String;
var I:Integer;
begin
  SetLength(Result,0);
  for I:=1 to Length(Line) do Result:=Result+IntToHex(Ord(Line[i]),2);
end;

Podmień IntToHex() na napisaną IntToBin() i będzie binarnie

0

To znam, a jak zrobić aby całą zawartość pliku załadował do zmiennej, a później w jakiejś pętli to zamieniał?

0

Skorzystać z TFileStream lub coś w rodzaju (ale to nie będzie wydajne przy większych plikach):

Var F: File of Char;
    C: Byte;
    Str: String = '';
Begin
 AssignFile(F, plik);
 Reset(F);
 While (not EOF(F)) Do
 Begin
  Read(F, C);
  Str += C; // Str := Str+C;
 End;
End;
0

Zrobiłem tak:

var
  S : String;
  NewStr, OldStr : String;
  Source : TextFile;
  F: File of Char;
  C: Byte;

begin
  Source := ParamStr(1);
  AssignFile(Source, 'E:\Plik.txt');
  if FileExists('E:\Plik.txt') then // Sprawdzenie, czy plik istnieje
  begin
    Reset(Source); // jeżeli tak - otwórz do odczytu
    while not Eof(TF) Do
    begin
      Read(F, C);
      Str += C; // Str := Str+C;
    end;
  end;
  Flush(Source);
  CloseFile(Source);
  Readln;

Ale pisze mi: E2015 Operator not applicable to this operand type w linicje:

Source := ParamStr(1);
0
  Source := ParamStr(1);
  AssignFile(Source, 'E:\Plik.txt');

Coś tu jest nie tak - zgadnij co.

0

Wiem, wpisałem w inny parametr, ale nadal nie działa.

0

Wrzuć aktualny kod + co to znaczy "nie działa"?

0

Usunąłem prawie wszystko:

program compilator;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  F: File of Char;
  C: Byte;
  Str: String = '';
  Source : String;

begin
  Source := ParamStr(1);
  AssignFile(F, Source);
  Reset(F);
  while (not EOF(F)) Do
  begin
    Read(F, C);                                          ---> * Błąd 1
    Str += C;                                            ---> * Błąd 2
  end;
end.

Pojawiające się teraz błędy:

[dcc64 Error] compilator.dpr(22): E2010 Incompatible types: 'Char' and 'Byte'.        ---> * Błąd 1
[dcc64 Error] compilator.dpr(23): E2029 Expression expected but '=' found             ---> * Błąd 2

Ostrzeżenia:

[dcc64 Warning] compilator.dpr(23): W1058 Implicit string cast with potential data loss from 'string' to 'ShortString'
0

Błąd 2 pewnie bierze się z tego, że Delphi jest ubogie w ułatwiające życie operatory, takie jak +=, więc zamień tę linijkę na Str := Str+C;.

0

Tak też zrobiłem, ale pojawiają mi się same ??????????

Aktualnie korzystam z Embarcadero RAD Studio XE3.

0

Może spróbuj użyć AnsiString oraz AnsiChar.
A te pytajniki pojawiają się w konsoli podczas próby wyświetlania tego co wczytałeś z pliku, tak?

0

Tak. Zamieniłem, działa, a nawet nie wiem co to zmienia.
Tylko pozostaje jeszcze jeden problem, otóż jak już na początku pisałem pliki będą w kodowaniu DOS, czyli OEM(bo chyba tak ono się nazywa). Program wyświetla wszystko dobrze, ale jak zmienie kodowanie pliku na OEM to pokazuje krzaczki. Jakieś rozwiązanie?

0

A wie ktoś jak przkonwertować ciąg znaków, właściwie zmienną z zawartością pliku w postać binarną(01010101011001001010010101)?

Przykład: http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/Binary_to_Text.asp

0

https://www.google.pl/search?q=konwersja+liczb+dziesi%C4%99tnych+na+dw%C3%B3jkowe&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:pl:official&client=firefox-a
Zmiana Char na Liczbę: X:=Ord(Ch); Zmiana Liczby na Char Ch:=Char(X);
Odczyt pliku już ci podano.

Radzę zacząć od prostego kursu i prostych rzeczy, ten dosyć prosty projekt ewidentnie cię na razie przerasta.

0

Ale to kupa roboty jest, nie ma jakiejś funkcji?

0

Dobra podpiąłem to jakoś, ale nie wiem dokładnie co to mi miało zrobić. Niby zmienia na liczby, ale nie takie jakie chciałem, jak to zmienić?

Kod:

program compilator;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  F: File of AnsiChar;
  C: AnsiChar;

  StrTEXT: RawByteString = '';
  StrBIN: RawByteString = '';
  Source : String;

begin
  Source := ParamStr(1);
  AssignFile(F, Source);
  Reset(F);
  while (not EOF(F)) do
  begin
    Read(F, C);
    StrTEXT := StrTEXT+C; // Str := Str+C;
    StrBIN := StrBIN+IntToStr(Ord(C)); // Str := Str+C;
  end;
  Writeln(StrTEXT);
  Readln;
  Writeln(StrBIN);
  Readln;
end.
0

Zmienia na liczby dziesiętne.
Na/w internecie poczytaj o zamianie na binarne, czy jakiekolwiek tam chcesz.

0

A to zadziała dołączając do kodu: Pełne Dec to Bin

0

Dołącz i się przekonaj?

0

Właśnię próbuję...

A jak zrobić aby przekształcanie na dec odbywało się po zamianie linijek?

Kod:

begin
  if ParamStr(1) = '/compile' then
  begin
    // Initialization - Read ---------------------------------------------------
    AssignFile(SourceFile, ParamStr(2));
    Reset(SourceFile);

    // Reading from file -------------------------------------------------------
    while (not EOF(SourceFile)) do
    begin
      Read(SourceFile, C);
      StrTEXT := StrTEXT+C; // Str := Str+C;
      StrBIN := StrBIN+IntToStr(Ord(C)); // Str := Str+C;                          //---> Zamiana Tekst na Dec po zamianie linijek
    end;

    // Changing references -----------------------------------------------------
    StrTEXT := StringReplace(StrTEXT, '1', '2', [rfReplaceAll]);                   //---> Po tym

    // Initialization - Write --------------------------------------------------
    AssignFile(TargetFile, ParamStr(2) + '.ap_bin');
    ReWrite(TargetFile);

    // Write to file -----------------------------------------------------------
    Write(TargetFile, StrBIN);
    Readln;

    Writeln(StrTEXT);
    Readln;
    Writeln(StrBIN);
    Readln;
  end;
end.
3

A jak zrobić to... a jak zrobić tamto... a jak zrobić sramto... www.google.pl oraz Kompendium i przestań spamować na forum

2

Tak w roli ścisłości - podana przez Ciebie @Juby_PW w linku funkcja IntToBin wydaje się podejrzana, bo dla argumentu Value = 1 i Digits = 8, funkcja zwraca dziewięcioznakowy ciąg 000000001, a powinna zwrócić 00000001 (osiem znaków jako Byte); Poza tym warunek można zamienić na statyczną macierz indeksowaną typem Boolean z cyframi dla liczby binarnej:

function IntToBin(const AValue: Integer; const ADigits: Integer): AnsiString;
const
  BIN_VALUES: array [Boolean] of Char = ('1', '0');
var
  I: Integer;
begin
  Result := '';

  for I := Pred(ADigits) downto 0 do
    Result := Result + BIN_VALUES[AValue and (1 shl I) = 0];
end;

teraz dla argumentów odpowiednio 1 i 8 funkcja zwróci ciąg 00000001, więc o poprawnej długości (dla wartości nieujemnych oczywiście);

EDIT: Zakręciłem się - dla dowolnych liczb z zakresu [Low(Integer) .. High(Integer)] zadziała; Przedtem coś mi nie poszło - teraz jest wszystko w porządku (mam nadzieję - jak coś to poprawcie mnie);


@babubabu & @szopenfx - tylko ostrożnie z tą "konstruktywną krytyką" :]

0

Działa!
A jak zrobić aby zmieniał to w drugą stronę?

0
  for I := Pred(ADigits) downto 0 do
    Result := Result + BIN_VALUES[not (AValue and (1 shl I) = 0)];

lub

  for I := Pred(ADigits) downto 0 do
    Result := Result + BIN_VALUES[AValue and (1 shl I) <> 0];

:D

0

Nie działa, albo nie tak jak trzeba... A co mam podstawić pod 2 parametr?

0
Juby_PW napisał(a)

U mnie nie, a co ty podstawiasz że ci odwraca? Ja próbuję 01000101 i powinno wyjść 69. A wychodzi: 01011010.

Teraz przynajmniej mam pewność, że nie analizujesz podanych kodów, tylko beztrosko je przeklejasz... Gdybyś przeanalizował to, co podałem w drugim poście to zauważyłbyś, że wartość logiczna z przesunięcia biowego i sumy jest negowana, więc wszystkie cyfry w ciągu wynikowym będą znegowane (zamiast 0 będzie 1, a zamiast 1 wyjdzie 0);

Więc skoro nie analizujesz kodu to nie wiem czy jest sens Ci go podawać, bo i tak tylko go przekleisz bez zrozumienia;


Żeby odwrócić konwersję trzeba napisać funkcję BinToInt - w argumencie podać ciąg znaków (String czy AnsiString), a zwrócić wartość liczbową (tu: Integer); Ale i tak należy napisać algorytm w zupełnie inny sposób, więc tego samego do odwrotnej konwersji nie wykorzystasz;

W sieci jest pełno materiałów na temat algorytmów konwertujących liczby na różne systemy i z powrotem, więc proszę - zajrzyj na Google i coś w końcu poczytaj i przetestuj.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.