Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

If I want to make package-code completely unreadable, in a way that the end-user can only call my functions, but has no way to re-engineer my definitions, how would I do that?

I know I can use Encode to make scrambled code which, quoting the doc, cannot be converted back by any Mathematica function. But even with an encoded package, the user could look at the definitions of my functions. So I should add some attributes: Protected, ReadProtected, Locked.

Would that be enough? Has someone experience with this?

Additional question: How do I distribute this? In the Workbench one has to process all Documentation files and can then create a .zip or a .tgz from its package, but there are unencoded files used. Do I have to encode the files by a script or is there already a solution?

share|improve this question
    
There is the function DumpSave[] which allows you to write definitions into a file that is not quite human-readable... –  J. M. Feb 10 '12 at 7:38
    
But DumpSaved files are possibly not readable on another system. It's the same point which @Szabolcs had in his "data storage question" –  halirutan Feb 10 '12 at 7:41
    
You might want to look into what these guys did for their Mathematica packages; you can only download an encoded version, and the human readable versions can only be obtained through special circumstances. –  J. M. Feb 10 '12 at 7:45
    
It seems you need a password even for downloading the encoded packages. –  halirutan Feb 10 '12 at 7:54
    
Related: How safe is Encode? –  Szabolcs May 28 '12 at 8:51
add comment

3 Answers

up vote 15 down vote accepted

My suggestion is to use a combination of encryption, DumpSave (as noted in some answers / comments), and Locked / ReadProtected, which should give your code a reasonable level of security. You can't make things totally safe, in Mathematica or any other language. Using DumpSave however means that you should create a version of a package for each platform you want to support. But, if you really want to protect your code, this extra work does not seem that unreasonable.

share|improve this answer
add comment

Mathematica-Users.org says:

The basic idea is to include commands at the end of your package which set the attributes of your "secret" functions to be ReadProtected, and then Locked. The ReadProtected means no one can see the function definitions, and the Locked means no one can undo the ReadProtected attribute.

It is probably not a good idea to also set the attribute Protected, because with Locked also engaged, your users will not be able to SetOptions on your functions.

The package file is still human readable and offers no protection from prying eyes. Saving the notebook as a package file in ".mx" format with the attributes set as indicated, offers protection from peepers, since the mx file is not human readable, but this option has some issues, mentioned above.

An alternative is to encode the package file with the Encode routine. This encrypts the package file, such that it is no longer human readable, but because it is an ASCII text file it is more portable. There is an exception to this portability - Linux encodes files differently from OS X and Windows.

The Needs or Get commands can read in the Encoded package file (possibly requiring a password, if you set one) and decrypt it, and once the package is in memory, the Locked and ReadProtect attributes now protect the secrets in your code. Here we give an example of this. We first show a trivial package that is written in a notebook, and saved as "demo.nb", for example. Since it's a tiny package it might contain only one cell, whose Cell Properties are set to "Initialization Cell". Here we assume the "secret function" we want to protect is the function "encrypt".

See the link for more.

I believe you must accept making OS-specific packages. This is what I recall from a MathGroup thread that I cannot currently find.

share|improve this answer
1  
I think that the information about the OS dependency might not be correct anymore for version 8. If my memory isn't fooling me for earlier versions a package encoded on linux could be read everywhere but not the other way round. I think with 8 it should now work across all remaining platforms but can't find a reference nor test it right now. If one is after maximal security, distributing code in .mx format might be a better choice, as mentioned in Leonids answer. –  Albert Retey Feb 11 '12 at 22:58
add comment

Something I once tried, but never really used, so no guarantees - but perhaps it is useful as a template:

LockContext[
  ctx_: ToString[
    Context[]]] := SetAttributes[Evaluate[ctx <> # & /@
     Names[ctx <> "*"]], {ReadProtected, Locked}]

This takes all defined symbols in ctx (default: current context) and applies some additional attributes to them. You could use this at the end of a package (respectively at the end of each - esp. the Private` context) to lock all relevant contexts and then save the encoded version (which is probably enough protection for the average honest user).

share|improve this answer
2  
By assigning to Attributes you are deleting any attributes already set (like Flat or HoldAll), and thus potentially changing the semantics of the code. –  celtschk Feb 10 '12 at 14:35
2  
Done. Note that I've used the fact that SetAttributes can take a list as first argument to further simplify the code. –  celtschk Feb 11 '12 at 10:16
1  
I just noticed that you should be able to easily get around this by loading the module inside a block like this: Block[{Locked=ReadProtected},Get["yourpackage`"]]. –  celtschk Feb 14 '12 at 18:19
3  
Not anymore in Version 9, since now, finally, Locked is Locked ... –  Rolf Mertig Dec 30 '12 at 16:47
1  
@RolfMertig - Did you ever get to doing this? Any additional thoughts? –  Jagra Apr 25 at 12:34
show 8 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.