Page 1 of 1

Explain it!

Posted: Tue Oct 21, 2008 2:15 pm
by ~~Wind~~
~~Wind~~ wrote:
Spoiler: εμφάνιση/απόκρυψη
για τους τολμηρους :-D

Code: Select all

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"++++\
+++++++++\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}



Επειδη πολλοι ρωτησατε τι και πως :-p
Τελικα ειναι πιο απλο απ οτι φαινεται ;)

Το προγραμμα αυτο σταλθηκε στο 1ο διαγωνισμο Obfuscated C Contest απο καποιον πολυ σχετικο με την C, κ προφανως ειναι γραμμενο σε C.
O συγγραφεας δεν ειπε ονομα καθως επιθυμει να μεινει ανώνυμος μεχρι κ σημερα.
Η αρχικη του μορφη ειναι η εξης:

Code: Select all

int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}


ας το δουμε τωρα λιγο πιο προσεχτικα

Code: Select all

int i;
main(){
    for( ; i["]<i;++i){--i;}"]; read('-'-'-',i+++"hell\
        o, world!\n",'/'/'/') );
}

read(j,i,p){
    write(j/p+p, i---j, i/i);
}


Πολυ ωραια, ηδη αρχισαν να ξεκαθαριζουν τα πραγματα

Η for: @Para μια for εχει τρια μερη
for ( 'ορισζουμε εναν μετρητη συνηθως' ;
'συγκρινουμε τον μετρητη με καποια μεταβλητη αλλη' ;
'κανουμε μια ενεργεια' )
Κανεις ομως δε μας επιβαλλει να εχουμε οπωσδηποτε αυτον τον μετρητη.. μπορουμε να εχουμε οτι θελουμε εκει.
Η for κανονικα μεταφραζεται --> ( οσες φορες γινεται κατι εκει μεσα ) { κανε κατι; }
Παρε τωρα την απειρη επαναληψη --> for (;;) τι σημαινει αυτο ? ;)

Η δικα μας for :

Code: Select all

for( ; i["]<i;++i){--i;}"]; read('-'-'-',i+++"hell\
        o, world!\n",'/'/'/') );

αποτελειται επισης απο 3 μερη. Δεν αρχικοποιει τπτ, αφου κατι τετοιο δε χρειαζεται. Οριζει εναν πινακα --> i["]<i;++i){--i;}"] και καλει την μεθοδο read();

Tι λεει μεσα στη read ?

Code: Select all

read( '-' - '-', i++ + "hell\
        o, world!\n", '/' / '/' ) );

αφαιρει το '-' απο το '-'. Αφαιρεση μεταξυ char. Αυτο μας κανει 0. :smt001
Διαιρει το '/' με το '/'. Διεραιση μεταξυ char. Αυτο μας κανει 1. :smt001 :smt002
Δλδ:

Code: Select all

read( 0 , i+++"hell\
        o, world!\n" , 1 ) );


Παμε στην πραγματικη read()

Code: Select all

read(j,i,p){
    write(j/p+p, i---j, i/i);
}

γινεται :

Code: Select all

read(0, i, 1){
    write (j/p+p, i---j, i/i);
}


Η read καλει την write. Ας απλοποιησουμε την write

Code: Select all

write (j/p+p, i---j, i/i);

γινεται

Code: Select all

write (0/1+1, i---0, i/i);
«»
write (0+1, i--, 1);
«»
write (1, i--, 1);


Τωρα μπορουμε να βγαλουμε τα 0 κ 1 απο την read
Επισης μπορουμε να ξεφορτωθουμε την '\' που αλλαζει σειρα στο "Hell[\]o, world!"
Παρατηρήστε ακομα οτι το i στην read(0, i, 1) μεσα στην write μειωνεται (i--). Αυτο δεν εχει κανενα απολυτως νοημα αφου ειναι τοπικη μεταβολη και δε χρησιμοποιειται πουθενα αρα
Μεχρι τωρα εχουμε:

Code: Select all

int i; //global
main(){
    for( ; i["]<i;++i){--i;}"]; read( i++ + "hello, world!\n" ) );
}

read( i ){
    write( 1,  i, 1);
}


Μπορουμε πλεον να αντικαταστησουμε την read με την ιδια την write
Οποτε:

Code: Select all

int i;
main()
{
        for (; i["]i;++i){--i;}"]; write( 1, i++ + "hello, world!\n", 1 ));
}


To μονο που εχει μεινει παραξενο ειναι αυτος ο πινακας. Στη πραγματικοτητα ειναι ενας πολυ απλος πινακας.
i["]i;++i){--i;}"]; <--- Θα μπορουσε να εχει οτιδηποτε εκει μεσα, πχ i["ειμαι πολυ ομορφος"], δε πρεπει να σας μπερδευουν τα ]i;++...κλπ
καθως αποτελουν απλα ενα string.
To μονο που πρεπει να προσεξουμε ειναι το μηκος του πινακα να ειναι οσο η εκφραση που εμφανιζουμε (το string στην write δλδ)

Αυτο που γινεται τελικα δλδ ειναι οτι εμφανιζουμε ενα ενα τα γραμματα του "Hello, world!" - ενα γραμμα για καθε επαναληψη της for
μεχρι η for να φτασει στο τελος του πινακα i["]i;++i){--i;}"]

Ελπιζω να καταλαβατε :smt016

Μπορουμε τωρα να κανουμε το αρχικο κομματι κωδικα καπως ετσι

Code: Select all

int i;main(){for(;i["]["];read('-'-'-',i+++"++\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}

ωστε να ειμαστε σωστοι με τα ++ , ο πινακας επισης δεν εγινε διδιαστατος, .. :smt024

Αυτα, 14.15, το φαι με περιμενει .. :-D :smt016
πρεπει να στησω κ iptables σημερα.. :smt017 πφφ,..

Re: Explain it!

Posted: Tue Oct 21, 2008 2:26 pm
by proskopos
Και εγένετο φως... :)
~~Βαρδάρη~~ ρίξε λίγο νερό στο σβέρκο σου, γιατί έπιασες φωτίστα.... :smt005 :shaking2: :bom:

Re: Explain it!

Posted: Tue Oct 21, 2008 2:51 pm
by ~~Wind~~
proskopos wrote:Και εγένετο φως... :)
~~Βαρδάρη~~ ρίξε λίγο νερό στο σβέρκο σου, γιατί έπιασες φωτίστα.... :smt005 :shaking2: :bom:



Link

Re: Explain it!

Posted: Wed Oct 22, 2008 1:08 pm
by para
Η write τι ορίσματα παίρνει και τι κάνει;

Re: Explain it!

Posted: Wed Oct 22, 2008 1:55 pm
by ~~Wind~~
para wrote:Η write τι ορίσματα παίρνει και τι κάνει;


Λειτουργικα δεν εκανες ? :smt018 :-p

Code: Select all

ssize_t write(int fildes, const void *buf, size_t nbyte);

Γραφει nbyte bytes απο τον buffer που δειχνει ο δεικτης buf σε ενα προκαθορισμενο ρευμα.

Code: Select all

 write( 1,  i, 1);

Γραφει 1 byte απο το i στο ρευμα εξοδου (stdout)

Σε Unix/Linux τα ρευματα εχουν ως εξης
0 - ρευμα εισοδου (stdin)
1 - ρευμα εξοδου (stdout)
2 - ρευμα διαγνωστικων μηνυματων (stderr)
3,4,.... περιγραφιτες αρχειων (fildes = file descriptors)

Re: Explain it!

Posted: Wed Oct 22, 2008 4:42 pm
by Joanna
Amazing! :) ~~Άνεμε~~ όρισες!

Spoiler: εμφάνιση/απόκρυψη
~~Wind~~ you rule! :-D

Re: Explain it!

Posted: Wed Oct 22, 2008 5:17 pm
by rose
Ο Wind έχει πορωθεί τελείως, ειναι σε καλό δρόμο. :smt016

Re: Explain it!

Posted: Wed Oct 22, 2008 7:49 pm
by para
Joanna wrote:~~Άνεμε~~ όρισες!
Κατά το "έγραψες";; :smt042 :smt042 :smt042


~~Wind~~ wrote:Λειτουργικα δεν εκανες ? :smt018
Ωχ.. τέτοια θα κάνουμε; Ευτυχώς τα κάνει η Βάνα :smt109

Καλή δουλειά ~~Wind~~ :smt023

Re: Explain it!

Posted: Wed Oct 22, 2008 9:14 pm
by Joanna
para wrote:Κατά το "έγραψες";; :smt042 :smt042 :smt042

Όχι, κατά το "you rule" ανόητε!!! :-D :-D