• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r4wp

[Rebol School] REBOL School

Kaj
2-Jan-2013
[1622]
By the way, your first example starts with garbled HTML
MaxV
2-Jan-2013
[1623]
Yes, I noticed it. Just corrected.
Kaj
2-Jan-2013
[1624]
Thanks
Endo
3-Jan-2013
[1625]
Isn't that interesting?
>> ? #a
#a is an issue

>> copy/part next #aaaa 2
== #aa ;<-- issue!

>> pick #aaa 2
== #"a"  ;<-- char!

Why the last one is not an issue?
Jerry
3-Jan-2013
[1626x2]
in R2, issue! is string!, So PICK gets char!. COPY retain the datatype, 
which is issue here.
in R3, you cannot COPY and PICK a issue!, because it's not string 
any more.
BrianH
3-Jan-2013
[1628x3]
(Pardon the level-up in the lesson.)

That's not necessarily the case for R3, it's just the case *now*. 
COPY and PICK are just actions, which could easily be defined for 
the issue! type. You could get most of the R2-like behavior for issues 
in R3 by emulating the way tuples pretend to be series when they're 
really not.


The type classes in Rebol aren't like base classes in OOP languages, 
they are more like behavioral conventions, and those conventions 
are more like Go interfaces than anything OOP. Something is series-like 
to the extent that it behaves like a series is supposed to behave. 
But the acrions that are defined for series types are in some cases 
also defined for other types as well, and the corresponding behavior 
for those types can be similar enough to that of series to allow 
both series and, say, tuples, to be operated on by the same code. 
All that matters is how it seems to act from the outside, not what 
it really is.
We've been making this even more the case in R3 and R2 lately, such 
as when we allowed SELECT to be used on objects (and maps in R3), 
since that is a function that is used to make series act like objects. 
Or when we allowed APPEND to work on objects and maps in R3, since 
there was a corresponding behavior that could be defined for those 
types, but didn't do the same for INSERT because its positional return 
value has no corresponding concept for object-like types.
For issues, we could have COPY return another issue of the same spelling, 
COPY/part return another issue spelled like that portion of the original 
(only integer part values, not offset positions because words don't 
have positions), and PICK return a character just as if the issue 
was a character container like strings are. We would have to avoid 
the positional functions, and the modifying functions could retern 
a different version the way that they do for the similarly immutable 
tuples, but the rest could be emulated as-is.
caelum
31-Jan-2013
[1631]
So I have a block
	account: make object! [
	  name: "James"
	  balance: $100
	  ss-number: #1234-XX-4321
	  deposit:  func [amount] [balance: balance + amount]
	  withdraw: func [amount] [balance: balance - amount]
	]

and I save it

	save %account-object account

then I read it back in

	new-account: load %account-object

account is an object, whilst new-account is a block.


My question is, how do I load the object into new-account as an object? 
So I end up with another object, not a block
GrahamC
31-Jan-2013
[1632]
Have you tried

new-account: do load %account-object
caelum
31-Jan-2013
[1633]
Ah, of course, the missing 'do' word to make it evaluate! Thanks 
GrahamC.
Pekr
31-Jan-2013
[1634]
btw - do might be unsecure, e.g. with CGI code. Maybe 'construct 
would do the trick too, without evaluating the stuff?
caelum
31-Jan-2013
[1635]
I see what you mean. I just read the function summary for 'construct'. 
My objects are encrypted before they get saved anywhere. Thanks for 
the tip Pekr.
Endo
1-Feb-2013
[1636]
you can also use SAVE/ALL to save in serialized form:
>> o: context [a: 1] save/all %file.r o p: load %file.r type? p
== object!
caelum
1-Feb-2013
[1637]
Very usefull. Just what I like about Rebol Thanks Endo.
Maxim
1-Feb-2013
[1638]
the most secure method is to SAVE/ALL AND CONSTRUCT.


also, btw, using MOLD/ALL can save a lot of ram because things like 
hash! and objects! do not get double allocated.  on big datasets 
like I'm  using it means saving 100MB RAM on app startup . :-)


just be carefull with save/all & mold/all   they can corrupt some 
data types just like when /ALL  isn't used.  it does allow much more, 
but it still can create some un-reloadable issues... always test 
it with your current data structures before blindly adopting it.
Endo
1-Feb-2013
[1639]
Yes, here is an example:
>> save/all %file.txt o context [a: self]
>> load %file.txt
** Syntax Error: Missing ] at end-of-script

file.txt file is:
#[object! [
    a: #[object! [...]   ;<---
]]
Maxim
1-Feb-2013
[1640x2]
cyclical data cannot be serialized by any of the internal tools.
though one can write his own mold function which handles the above 
(I once did so).   its just tedious to support all types (there are 
so many)
BrianH
1-Feb-2013
[1642x3]
Caelum, SAVE/all and MOLD/all will have trouble saving your example 
object in a restorable state. The problem is those functions defined 
in the object, and bound to its fields. Those bindings won't be restored. 
For data that has to be saved and restored safely you're better off 
with having functions that operate on objects, rather than objects 
with functions in them. The "safely" part actually refers to not 
executing code, and you have to execute code to create functions. 
It's better to put your code in one file which you can protect, and 
your data in another file which you can be more wary of.
Rebol isn't class-based. In class-based languages, that separation 
of code and data happens automatically - code is class definitions, 
data is instance creation. In Rebol, if you need to keep your code 
and data separate you have to do it yourself.
In this case, you keep your code and data separate because code is 
best saved with MOLD and reconstructed with DO, but data of types 
that don't have a normal literal form (but aren't affected by binding) 
are often better saved with MOLD/all and restored with LOAD. The 
main thing is that we don't have a literal syntax to declare word 
bindings; instead, we have a way to construct them with code. Same 
goes for cyclic or DAG structures that aren't strictly nested. So, 
if you need to create such things, you need to run code. And you 
need to keep your untrustworthy data that you can't safely DO separate 
from that code.
caelum
2-Feb-2013
[1645]
Thanks BrianH. I am aware of the need to "keep your untrustworthy 
data that you can't safely DO separate from that code."


I am creating a small Rebol server capable of communicating with 
clients, using RSA key exchange and the blowfish algorithm, both 
of which work to reasonably high encryption levels in Rebol, 4096 
for RSA and 512 for Blowfish (yes I know the effective upper limit 
for Blowfish is 448 bits, but that is good enough for my purposes).


I want to save the RSA key as a block so it can be loaded back into 
the program and used again, hence my question. It will be encrypted, 
wherever it gets saved, so there will be no chance of it being messed 
with.


Actually, I am writing a much simpler version of Rebol Services, 
since I could not get that to work and my ability to code in Rebol 
was not sufficiently developed yet to see how to get it working.


I am in a steep learning curve right now with Rebol and the time 
I am investing is starting to pay off. Thanks for the information 
about keeping code and data separate. It's always good to be reminded 
of 'obvious' truths.
Reichart
2-Feb-2013
[1646]
Francis, if you search through the Qtask source, you will find a 
448 encryptor writte in JS that runs in the browser, you might enjoy 
how we did it.
caelum
8-Feb-2013
[1647]
So I have 

mailbox: open [
    scheme: 'pop
    user: "[user-:-domain-:-org]"
    pass: "password"
    host: "mail.domain.org"
]


and I am getting my email as expected. Two questions. Is my password 
being encrypted by Rebol when it communicates with my mail server? 
How do I know?
GrahamC
8-Feb-2013
[1648x3]
trace/net on
and then see the exchange
From memory, pop supports apop.
If you want encryption, use pops or spop
caelum
8-Feb-2013
[1651]
Replacing pop with apop, spop or pops in mailbox all produce the 
same error:
    ** Access Error: Invalid port spec: scheme apop
GrahamC
9-Feb-2013
[1652]
See here http://stackoverflow.com/questions/1128826/downloading-mail-from-hotmail
caelum
23-Feb-2013
[1653]
So I have a question about RSA encryption. When I run the following 
code:

  rsa-key: rsa-make-key
  rsa-generate-key rsa-key 1024 3

  crypt-key: copy/part checksum/secure mold now/precise 16
  print crypt-key

  crypt-key: rsa-encrypt rsa-key crypt-key
  print crypt-key

  crypt-key: rsa-encrypt/private/decrypt rsa-key crypt-key
  print crypt-key


it runs perfectly, encrypts the crypt-key and then decrypts it sucessfully.


As you probably know, the purpose of the RSA algorithm is to allow 
someone else to encrypt data that only you can decrypt using your 
private key. I tried this with a different public key using the following 
code:

  rsa-key1: rsa-make-key
  rsa-generate-key rsa-key1 1024 3

  rsa-key2: rsa-make-key
  rsa-key2/n: rsa-key1/n

  crypt-key: copy/part checksum/secure mold now/precise 16
  print crypt-key

  crypt-key: rsa-encrypt rsa-key2 crypt-key
  print crypt-key

  crypt-key: rsa-encrypt/private/decrypt rsa-key2 crypt-key
  print crypt-key


So I put the public key from rsa-key1 into another object, rsa-key2 
and tried using it to encrypt the data and get the following error.

	#{DD44AC1810E9A7020FAD72A7CFA54100}
	Segmentation fault


How do I get the public key from the first object into the second 
object so that it can be used to encrypt data?
Cyphre
23-Feb-2013
[1654x4]
caelum, I corrected your non-working exaple:
;key1 - contains public and private keys
rsa-key1: rsa-make-key
rsa-generate-key rsa-key1 1024 3

;key2 - contains only public key
rsa-key2: rsa-make-key
rsa-key2/e: 3
rsa-key2/n: rsa-key1/n

;data to ecrypt encrypt 
data: copy/part checksum/secure mold now/precise 16

;encrypt data using the key2 (with pub key only)
crypt-key: rsa-encrypt rsa-key2 data


;decrypt data(that have been encrypted using key2) using the key1(needs 
to contain private key)
data2: rsa-encrypt/private/decrypt rsa-key1 crypt-key

either equal? data data2 [
	print "decrypted data match the original - decription passed"
][

 print "decrypted data differs from the original - decryption failed"
]
the problem was you forgot to set the generator value (key/e) when 
makeing rsa-key2
and also you tried to decrypt the data using rsa-key2 which doesn't 
contain the private key
caelum
23-Feb-2013
[1658]
Got it! Thanks Cyphre, much appreciated.
caelum
27-Feb-2013
[1659]
Another question. On linux (linux mint debian) these segments of 
code are part of a larger program. I separated them out because they 
are causing trouble when I try to 'enface' them.


    set-net [[me-:-mydomain-:-net] mail.mydomain.net pop.mydomain.net none 
    none none "[me-:-mydomain-:-net]" "PASSWORD"]


    open [scheme: 'pop user: "[me-:-mydomain-:-net]" pass: "PASSWORD" host: 
    "mail.mydomain.net"]


The code encapsulates without errors, but when I run the program 
after 'enface' it gives the following errors:

    Set-Net not provided.

    ** Access Error: Invalid port spec: scheme pop user [me-:-mydomain-:-net] 
    pass PASSWORD host mail.mydomain.net

    ** Near: open [scheme: 'pop user: "[me-:-mydomain-:-net]" pass: "PASSWORD" 
    host: "mail.mydomain.net"]


I would like to be able to 'enface' these code snippets. Any suggestions 
as to how to fix this would be most welcome?
GrahamC
27-Feb-2013
[1660]
if set-net is not defined, get the source and add it to your script
caelum
27-Feb-2013
[1661x2]
set-net is in the source exactly as above, 'enface' is refusing to 
compile it, but it compiles (almost) the rest of the program just 
fine.
I was wrong. Simple programs like (print "Hello World") compile and 
execute, but programs with a lot of code compile but produce a series 
of errors when executed. I noticed a pattern. Wherever a word is 
not followed by ':' causes errors, examples below. Perhaps it's just 
this linux version of enface?

    stylize [
        fld80: field 80x28 font-size 17 white ivory center
        .......
    ]

produces the error:

    ** Script Error: stylize has no value
    ** Near: new-styles: stylize [
        fld80: field 80x28 font-size 17 white ivory center 
        fld400: field 400x28 font-size 17 whit...

I'll try this on windows when I have the opportunity.
GrahamC
27-Feb-2013
[1663x2]
You haven't included view.r
without this no view or vid stuff will run after being encapped
caelum
27-Feb-2013
[1665]
Thanks GrahamC. Where do I find view.r? I just searched my whole 
HD for it. Not there.
GrahamC
27-Feb-2013
[1666x3]
it should be in the <sdk>/source directory
this is mine
#include %gfx-colors.r
#include %gfx-funcs.r

#include %view-funcs.r
#include %view-vid.r
#include %view-edit.r
#include %view-feel.r
#include %view-images.r
#include %view-styles.r
#include %view-request.r


;-- Must be done prior to loading anything that requires fonts on 
Linux.

layout [text "imanXwin kludge"] ;-throw this one away soon-- okay?

open-events
caelum
27-Feb-2013
[1669]
I just copied all the SDK stuff back onto my main HD and I found 
view.r. Thanks for that GrahamC. I'll retry encapping my program 
with the includes..
caelum
28-Feb-2013
[1670]
I have included view.r and now have the graphical elements working 
after 'enface', thanks GrahamC. But I'm still getting the other errors: 
This is all to do with setting up the email parameters:

    Set-Net not provided.

    ** Access Error: Invalid port spec: scheme pop user [me-:-mydomain-:-net] 
    pass PASSWORD host mail.mydomain.net

    ** Near: open [scheme: 'pop user: "[me-:-mydomain-:-net]" pass: "PASSWORD" 
    host: "mail.mydomain.net"]
GrahamC
28-Feb-2013
[1671]
If you did a grep on your source directory you'll find it ... in 
prot-setnet.r