Φτιάχνουμε μια φόρμα οθόνης 100 χαρακτήρες επί 48 γραμμές, για να βλέπουμε τα αποτελέσματα (χρησιμοποιώ μη αναλογική γραφή, το ένα γράμμα κάτω από το άλλο).
Η συνάρτηση δυαδ$() πήρε μια παράμετρο προαιρετική, το πόσα byte θα δείχνει. Π.χ. το πρώτο, τα δυο πρώτα, τα τρία πρώτα ή όλα (και τα τέσσερα), ενός 32 bit Unsigned Αριθμού. Δηλαδή χωρίς πρόσημο. Η συνάρτηση που κάνει την μετατροπή πρώτα σε δεκαεξαδικό Δεκαεξ() αν πάρει αρνητικό τον κάνει θετικό (παίρνει δηλαδή την απόλυτη τιμή).
Υπάρχει συνάρτηση που κάνει την μετατροπή ώστε ένας ακέραιος αρνητικός να μετατραπεί σε έναν unsigned (χωρίς πρόσημο) με ίδια bits. H Δυαδικό.Ακέραιο() δίνει τον Unsigned με ίδια bits, και η Ακέραιο.Δυαδικό() έναν Unsigned τον κάνει με πρόσημο (στα ίδια bits).
Εδώ δείχνω τη διαφορά αναστροφής των bits (από 1 σε 0 και το ανάποδο) με το αντίστροφο. Το αντίστροφο ενός αριθμού με πρόσημο Α είναι το -Α. Αντίστροφο δεν έχουμε σε αναπαράσταση χωρίς πρόσημο. Αναστροφή των Bits όμως μπορούμε να κάνουμε.
Δείτε ποια είναι η διαφορά αν προσθέσουμε τον unsigned A με τον αντίστροφο θα πάρουμε ένα δυαδικό με όλα τα Bit 1. Αυτός όμως σε signed integer είναι ο -1. Αν προσθέσουμε τον θετικό signed Α με τον signed - A τότε θα πάρουμε το 0, δηλαδή όλα τα bit 0.
Όπως γίνεται φανερό ο -Α, με Α θετική τιμή, έχει μια αναπαράσταση σε Bits το συμπλήρωμα του 2 στην τιμή του Unsigned με τα ίδια bits.
To δυαδικό.από() είναι το Xor, και βλέπουμε μια χρησιμότητα στο να αντιστρέφουμε όχι μόνο όλο τον unsigned αριθμό αλλά και όποια bit θέλουμε.
Βλέπουμε την Δυαδικό.Ολίσθηση και Δυαδική.Περιστροφή (εδώ η λέξη δυαδικό στο πρόθεμα της περιστροφής έχει γίνει δυαδική...και δεν θυμάμαι την σκοπιμότητα...αλλά ας το δεχτούμε έτσι). Οι αρνητικές τιμές κάνουν την ολίσθηση και την περιστροφή προς τα δεξιά (32bit) και οι θετικές στα αριστερά (από 31 ... -31).
Οι μεταβλητές
Μπορούμε να δηλώσουμε Μακρυς Α και να έχουμε έναν 32bit Long, όμως η χρησιμότητά του για τη Μ2000 είναι για να περνάμε τιμές σε κλήσεις εξωτερικών ρουτινών (dll).
H Για {} δουλεύει και με όλους τους
Αν θέλουμε βάζουμε την ανανέωση της οθόνης να γίνεται ας πούμε κάθε 0,3 του δευτερολέπτου. Οπότε η Τύπωσε φαίνεται να γίνεται μια φορά! (οι μονάδες είναι σε χιλιοστά του δευτερολέπτου. χωρίς τιμή το περιβάλλον κάνει άμεση ανανέωση οθόνης. Ουσιαστικά υπάρχει διπλή οθόνη αυτή που βλέπουμε και αυτή που ετοιμάζεται)
Σε wine μπορεί η γραμματοσειρά tahoma να μην είναι unicode. Σε αυτήν την περίπτωση πρέπει να δώσουμε το greek ή Ελληνικά για να χρησιμοποιηθεί σωστά. Έγινε αλλαγή το tahoma σε verdana που είναι unicode σε κάθε περίπτωση. (όταν δεν είναι unicode τότε φορτώνεται η γραμματοσειρά ανάλογα με την επιλογή κωδικοσελίδας, οπότε τα ελληνικά γράμματα μπορεί να λείπουν και εμφανίζονται τα τετράγωνα στην θέση τους.
ανανέωση 300
\\ μπορούμε να βάλουμε μια Διάβασε β αντί να δώσουμε τιμή
\\ και έτσι αν το τμήμα λέγεται α τότε με α 12 καλούμε το τμήμα με παράμετρο 12
\\ με tab και alt tab μπορούμε να βάζουμε/βγάζουμε εσοχές σε πολλές γραμμές μαζί (είτε διαστήματα είτε tab (ότι βρει ο διορθωτής).
\\ μπορούμε να μετακινούμε (ολισθαίνουμε πάνω κάτω) τις γραμμές σπρώχνωντας τες με το ποντίκι!
Γραμματοσειρά "Verdana"
Πένα 14
Οθόνη 1
β = 12
Συνάρτηση δυαδ$ {
Διάβασε μια_τιμή
Αν Ταύτιση("Α") τότε {
Διάβασε από_εδώ
από_εδώ=2*(ακ(4-από_εδώ) υπολ 4+1)-1
} Αλλιώς {
από_εδώ=1
}
δεκαεξαδική$ = Δεκαεξ$( μια_τιμή, 4 )
Πίνακας μια_τιμή$( 16 )
μια_τιμή$( 0 ) = "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
Εγγραφο Αα$
Για ι = από_εδώ Εως Μήκος( δεκαεξαδική$ )
Αα$ = μια_τιμή$( Εκφρ( "0x" + Μες$( δεκαεξαδική$, ι, 1 ) ) )
Επόμενο ι
= Αα$
}
Φόρμα 100,48 \\ χαρακτήρες πλάτος
Τύπωσε "Μετατροπή Δυαδικού από το " ; β ; " σε 32bits:"
Τύπωσε δυαδ$( β )
Τύπωσε δυαδ$( Δυαδικό.Αντίστροφο( β ) ); " Συμπλήρωμα ως προς 1 του " ; β
Τύπωσε δυαδ$( Δυαδικό.Αντίστροφο( β ) + 1 ); " Συμπλήρωμα ως προς 2 του " ; β
Τύπωσε δυαδ$( δυαδικό.ακέραιο(-β)); " Το -12 είναι το συμπλήρωμα του 2, σε δυαδική αναπαράσταση"
Τύπωσε δυαδ$( 0x1000 ) ; " ή 0x1000 δεκαεξαδικό"
Τύπωσε δυαδ$( 0xFFFF1000 ) ; " ή 0xFFFF1000 δεκαεξαδικό"
Τύπωσε δυαδ$( #FFAA22 ) ; " #FFAA22 είναι το 0x22AAFF - έχουμε μια τιμή RGB (RED=255 ή 0xFF) "
\\ είναι το FF το οποίο είναι το τρίτο byte και όχι το πρώτο.
Τύπωσε δυαδ$( 0xFFAA22 ); " το 0xFFAA22 δεν είναι ίδιο με το #FFAA22"
\\ Μπορούμε να τυπώσουμε στο δεκαεξαδικό όπως στην Τύπωσε τυπώνουμε στο δεκαδικό.
\\ αρνητικές τιμές ή εκτός ορίων τυπώνονται με ???-
Δεκαέξ "ο αριθμός Χ=" ; 256, "το άθροισμα =" ; 0x0100 + 0xF0, "To 250067:", 250067
Δεκαέξ "Εδώ είναι το λάθος (βάλαμε αρνητικό):" ; - 1
Για Bytes=1 έως 4 {
Τύπωσε Δεκαεξ$(123,Bytes), δυαδ$(123,Bytes)
}
Για Bit=1 έως 8 ανα 2 {
Τύπωσε Δυαδ$(Δυαδικο.ολισθηση(123,Bit)); " Ολίσθηση αριστερά στο ";Bit;"o Bit"
}
Τύπωσε Δυαδ$(123) ; " Κανονικό - Αριθμός 123 ή 0x";Δεκαεξ$(123,1)
Για Bit=1 έως 4 {
Τύπωσε Δυαδ$(Δυαδικη.περιστροφη(123,-Bit)) ; " Περιστροφή δεξιά στο ";Bit;"o Bit"
}
α=Δυαδικη.περιστροφη(123,-4)
Τύπωσε μορφή$("Δυαδικός ως ακέραιος με πρόσημο: {0} και χωρίς {1}", ακέραιο.δυαδικό(α), α)
\\ αντιστροφή bits
Τύπωσε δυαδ$(δυαδικό.απο(α,0χffffffff)); " η πραγματική αναστροφή των Bits"
Τύπωσε δυαδ$(δυαδικό.αντιστροφο(α)); " Εδώ είναι λάθος το α έχει Unsign τιμή"
Τύπωσε "Το δυαδικό.αντίστροφο δουλεύει για αριθμούς με πρόσημο Sign και όχι Unsign"
Τύπωσε δυαδ$(δυαδικό.αντιστροφο(ακεραιο.δυαδικό(α))) ; " εκτός και αν το μετατρέπουμε σε Sign"
Τύπωσε δυαδ$(-1-(ακεραιο.δυαδικό(α))); " το ίδιο κανουμε και εδώ, επειδή ξέρουμε ότι ο α είναι αρνητικός"
Τύπωσε Δυαδ$(α)
Τύπωσε Δυαδ$(δυαδικό.και(α,0χff)); " διατηρούμε τα τελευταία δεξιά 8 bit, τα άλλα γίνονται 0"
Τύπωσε Δυαδ$(δυαδικό.και(α,0χff000000)); " διατηρούμε τα τελευταία αριστερά 8 bit, τα άλλα γίνονται 0"
Τύπωσε Δυαδ$(δυαδικό.η(α,0χAA00)); " κάνουμε συγκεκριμένα Bit 1"
Τύπωσε Δυαδ$(δυαδικό.απο(δυαδικό.η(α,0χAA00),0χF00)); " αντιστρέφουμε συγκεκριμένα bit"
Τύπωσε Δυαδ$(45)
Τύπωσε Δυαδ$(-45); " παίρνει την απόλυτη τιμή, δίνει ότι και η προηγούμενη"
Τύπωσε Δυαδ$(δυαδικό.ακεραιο(-45)); " δίνει το δυαδικό σε αναπαράσταση ακέραιου"
Τύπωσε μορφη$("Αριθμός χωρίς πρόσημο {0} που έχει τα ίδια bit με αυτόν {1}",δυαδικό.ακεραιο(-45), -45)
Στην έκδοση 8.2 αν 17 η συνάρτηση δυαδ$() γράφεται καλύτερα ως λάμδα συνάρτηση για να κρατάει μέσα της τον πίνακα μόνιμα, δηλαδή να μην τον δημιουργεί κάθε φόρα που εκτελούμε τη συνάρτηση. Φτιάχνουμε μια λάμδα που παράγει τη λάμδα που θέλουμε!
δυαδ0$=Λάμδα$ ->{
\\ αυτή η λάμδα παράγει μια άλλη, που έχει τον πίνακα κρατημένο στο περιβάλλον της
\\ δεν μπορούμε να επέμβουμε σε αυτόν, και είναι πια ένα αντικείμενο με έτοιμες τιμές.
Πίνακας μια_τιμή$( 16 )
μια_τιμή$( 0 ) = "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
\\ η δυαδ$ είναι μια λάμδα συνάρτηση που συλλαμβάνει τον πίνακα μια_τιμή$()
\\ οπότε δεν χρειάζεται να φτιάχνεται κάθε φορά!
= λάμδα$ μια_τιμή$()->{
Διάβασε μια_τιμή
Αν Ταύτιση("Α") τότε {
Διάβασε από_εδώ
από_εδώ=2*(ακ(4-από_εδώ) υπολ 4+1)-1
} Αλλιώς {
από_εδώ=1
}
δεκαεξαδική$ = Δεκαεξ$( μια_τιμή, 4 )
Εγγραφο Αα$
Για ι = από_εδώ Εως Μήκος( δεκαεξαδική$ )
Αα$ = μια_τιμή$( Εκφρ( "0x" + Μες$( δεκαεξαδική$, ι, 1 ) ) )
Επόμενο ι
= Αα$
}
}
δυαδ$=δυαδ0$()
Η άλλη περίπτωση είναι με την χρήση μιας Κατάστασης σε ένα αντικείμενο, χωρίς λάμδα συνάρτηση. Αντί να χρησιμοποιούμε την δυαδ.δ$() κάνουμε ένωση με μια νέα δυαδ$()
Η ένωση κάνει αυτό Βάλε &δυαδ.δ$() και μετά αυτό Διάβασε &δυαδ$(), δηλαδή βάζει την αναφορά της δυαδ.δ$() στην νέα δυαδ$()
Εδώ μπορούμε να επέμβουμε στην ομάδα μετά την χρήση της δυαδ$(), γιατί είναι ανοικτή στο πρόγραμμα, ενώ αν ήταν σε λάμδα συνάρτηση θα ήταν απροσπέλαστη από έξω. Και στην ομάδα μπορούμε να δηλώσουμε ιδιωτικά κάποια μέλη της, αλλά μπορεί να πάρει συναρτήσεις που να επεμβαίνουν σε αυτές ακόμα και προσωρινά.
Ομάδα δυαδ {
Κατάσταση δυαδική_τιμή = 0:="0000",1:= "0001",2:= "0010", 3:="0011",4:= "0100", 5:="0101", 6:="0110", 7:="0111", 8:="1000", 9:="1001", "A":="1010", "B":="1011", "C":="1100", "D":="1101", "E":="1110", "F":="1111"
Συνάρτηση δ$ {
Διάβασε μια_τιμή
Αν Ταύτιση("Α") τότε {
Διάβασε από_εδώ
από_εδώ=2*(ακ(4-από_εδώ) υπολ 4+1)-1
} Αλλιώς {
από_εδώ=1
}
δεκαεξαδική$ = Δεκαεξ$( μια_τιμή, 4 )
Εγγραφο Αα$
Για ι = από_εδώ Εως Μήκος( δεκαεξαδική$ )
Αα$ = .δυαδική_τιμή$( Μεσ$( δεκαεξαδική$, ι, 1 ) )
Επόμενο ι
= Αα$
}
}
Ένωσε δυαδ.δ$() στο δυαδ$()
Το πιο ανεβασμένο πρόγραμμα (είναι στο Info στην εγκατάσταση):
// The original RIPEMD function was designed in the framework of the EU project RIPE (RACE Integrity Primitives Evaluation) in 1992
// RIPEMD-160 is 160bit cryptographic hash function.
Module Checkit {
Function Prepare_RiPeMd_160 {
Dim Base 0, K(5), K1(5)
K(0)=0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E
K1(0)=0x50A28BE6,0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000
Dim Base 0,r(80), r1(80), s(80), s1(80)
r(0)=0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
r(16)=7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
r(32)= 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
r(48)=1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
r(64)=4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
k=r() : k*=4 ' k is a pointer to array. We have to multiply to make them offsets
r1(0)=5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
r1(16)=6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
r1(32)=15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
r1(48)=8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
r1(64)=12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
k=r1() : k*=4
s(0)=11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
s(16)=7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
s(32)=11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
s(48)=11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
s(64)=9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
s1(0)=8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
s1(16)=9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
s1(32)=9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
s1(48)=15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
s1(64)=8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
Dim Base 0, T(5), TT(5)
T(0)=lambda ->binary.xor(binary.xor(number,number),number)
T(1)=lambda (B,C,D)->binary.or(binary.and(B,C), binary.and(binary.not(B), D))
T(2)=lambda ->binary.xor(binary.or(number, binary.not(number)), number)
T(3)=lambda (B,C,D)->binary.or(binary.and(B,D), binary.and(C,binary.not(D)))
T(4)=lambda ->binary.xor(number, binary.or(number, binary.not(number)))
// no need for variables we read form stack with number
TT(0)=lambda ->binary.xor(number, binary.or(number, binary.not(number)))
TT(1)=lambda (BB,CC,DD)->binary.or(binary.and(BB,DD), binary.and(CC,binary.not(DD)))
TT(2)=lambda ->binary.xor(binary.or(number, binary.not(number)), number)
TT(3)=lambda (BB,CC,DD)->binary.or(binary.and(BB,CC), binary.and(binary.not(BB),DD))
TT(4)=lambda ->binary.xor(binary.xor(number,number),number)
// return of this function is a lambda function
// all arrays are closures to this lambda
=lambda K(),K1(),TT(), T(),r(),r1(), s(), s1() (&message$, ansi as boolean=true, ansiid=1033)-> {
set fast!
def h0 = 0x67452301, h1 = 0xEFCDAB89, h2 = 0x98BADCFE
def h3 = 0x10325476, h4 = 0xC3D2E1F0
def i, j, l, padding, l1, blocks, acc, f64 as boolean=true, oldid
if ansi then oldid=locale : locale ansiid
// we use a buffer of 64 bytes
buffer clear message as byte*64
l=len(message$)*if(ansi->1,2 )
if binary.and(l,63)>55 then padding=64
padding+= 64 - (l Mod 64)
l1=padding+l+1
f64=binary.and(l,63)<>0
blocks=l1 div 64
rem
Print "blocks:";blocks
// now prepare the buffer
PrepareBuffer()
def decimal A, B, C, D, E, AA, BB, CC, DD, EE, T, TT
do
A = h0 : B = h1 : C = h2 : D = h3 : E = h4
AA = h0 : BB = h1 : CC = h2 : DD = h3 : EE = h4
for J=0 to 79 {
JJ=J DIV 16
PUSH binary.add(Binary.Rotate(binary.add(A,T(JJ)(B,C,D),eval(message ,r(j) as long),k(jj)), s(j)), e)
A = E : E = D : D = Binary.Rotate(C, 10) : C = B : READ B
PUSH binary.add(Binary.Rotate(binary.add(AA,TT(JJ)(BB,CC,DD),eval(message, r1(j) as long),k1(jj)),s1(j)),EE)
AA = EE : EE = DD : DD = Binary.Rotate(CC, 10) : CC = BB : READ BB
}
push binary.add(h1, C, DD)
h1 = binary.add(h2, D, EE)
h2 = binary.add(h3, E, AA)
h3 = binary.add(h4, A, BB)
h4 = binary.add(h0, B, CC)
Read h0
blocks--
rem
print over $(0,8), blocks : Refresh
if blocks=0 then exit
PrepareBuffer()
always
rem
print
buffer ans as byte*20
// we put ulong (long ar ulong in buffers)
Return ans, 0:=h0 as long, 4:=h1 as long,8:=h2 as long, 12:=h3 as long, 16:=h4 as long
=ans
if ansi then locale oldid
set fast
Sub PrepareBuffer()
if l-acc>=64 then
LoadPart(64)
else.if blocks=1 then
return message, 0:=string$(chr$(0),32)
if l-acc=0 and f64 then
Return message, 56:=l*8 as long, 60 :=binary.shift(l,-29) as long
else
Return message, l-acc:=0x80, 56:=l*8 as long, 60 :=binary.shift(l,-29) as long
if l>acc then LoadPart(l-acc)
end if
else
Return message, l-acc:=0x80
LoadPart(l-acc)
end if
End Sub
sub LoadPart(many)
// str$() convert to ansi, one byte per character
// using 1033 as Ansi language
if ansi then
Return message, 0:=str$(mid$(message$,1+acc, many))
else
Return message, 0:=mid$(message$, 1+acc, many)
end if
acc+=many
end sub
}
}
Module TestHash (RIPEMD){
Flush
// push data to stack of values, as fifo (each entry append to end of stack)
Data "b3be159860842cebaa7174c8fff0aa9e50a5199f","Rosetta Code"
Data "9c1185a5c5e9fc54612808977ee8f548b2258d31",""
Data "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe","a"
Data "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc","abc"
Data "5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"
Data "f71c27109c692c1b56bbdceb5b9d2865b3708dbc","abcdefghijklmnopqrstuvwxyz"
Data "b0e20b6e3116640286ed3a87a5713079b21f5189"
Data "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
Data "9b752e45573d4b39f4dbd3323cab82bf63326bfb", String$("1234567890",8)
rem Data "52783243c1697bdbe16d37f97f68f08325dc1528", String$("a",1000000)
While not empty
Read check$, text$
Print "RIPEMD160 for ";quote$(Left$(if$(len(text$)>30->left$(text$,27)+"...", text$),30))
// pass text$ by reference
Display(RIPEMD(&text$))
End While
sub Display(ans)
local answer$
for i=0 to len(ans)-1
answer$+=hex$(eval(ans,i),1)
next i
Print lcase$(answer$)
Print lcase$(answer$)=check$
end sub
}
TestHash Prepare_RiPeMd_160()
}
Checkit
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.