Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Lua ➜ How to do AES encryption with Lua and MUSHclient

How to do AES encryption with Lua and MUSHclient

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  3  

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Thu 09 Dec 2004 02:29 AM (UTC)

Amended on Mon 02 Oct 2006 08:50 AM (UTC) by Nick Gammon

Message
I have been interested in encryption for a long time, however it has been hard to distribute encryption utilities because of the laws passed by various governments to restrict their export.

To work around this, I will describe here a technique for making an encryption library for MUSHclient, to be used in Lua scripting.

The trick is that you need to obtain the actual source code for the AES encryption yourself, providing you are not breaking the laws of the land (whatever that country is) to do so.

You place those files into a directory, along with the "aeslib" Lua library, whose source is given below.

AES is based on the "Rijndael" algorithm by Joan Daemen and Vincent Rijmen.

Once assembled you should have the following files:


aes.c  aeslib.c    lauxlib.h  lua.lib     sha256.c
aes.h  aeslib.dll  lua.h      lualib.lib  sha256.h


Obtain the files from the following places (or others of your choosing):


  • aes.c and aes.h


    http://www.cr0.net:8040/code/crypto/aes/


  • sha256.c and sha256.h


    http://www.cr0.net:8040/code/crypto/sha256/


  • lua.h, lauxlib.h, lua.lib and lualib.lib


    http://www.gammon.com.au/files/mushclient/lua.zip


    You could also simply download Lua from the Lua site www.lua.org and compile it yourself to get those files.

    The files lua.h and luaxlib.h are part of the Lua source, once compiled they become the Lua libraries lua.lib and lualib.lib. That was with Visual C++ 6, if you compiled them under Cygwin you would get liblua.a and liblualib.a.

  • aeslib.c

    This is given below, and will also be available from:


    http://www.gammon.com.au/files/utils/aeslib.c


  • aeslib.dll

    This is the result of the compilation process below.


A simple way of compiling it to install the free Cygwin compiler for Windows. Here are some guidelines for doing that:


http://www.gammon.com.au/smaug/installingcygwin.htm


Once you have got your files assembled, compile them to produce the DLL as follows:


gcc -shared -o aeslib.dll aes.c sha256.c aeslib.c lualib.lib lua.lib


You now have a aeslib.dll file which you can place into the same directory as your other Lua DLLs.

Source for aeslib.c ...



/*

Lua library for AES encryption. 

You need to obtain various files yourself to compile it. See below for details.

Author of this file: Nick Gammon
Date: 10th December 2004

For more information, see: 

  http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=4988

  (C) Copyright Nick Gammon 2004. Permission to copy, use, modify, sell and
  distribute this software is granted provided this copyright notice appears
  in all copies. This software is provided "as is" without express or implied
  warranty, and with no claim as to its suitability for any purpose.


The AES implementations used here were written by Christophe Devine.

*/

#define LUA_API __declspec(dllexport)

#include "lua.h"
#include "lauxlib.h"

#include "aes.h"
#include "sha256.h"
#include <malloc.h>
#include <memory.h>
#include <stdlib.h>

#pragma comment( lib, "lua.lib" )
#pragma comment( lib, "lualib.lib" )

/* Uncomment this to provide a "test" function */

/* #define TEST */

/* 

  For more information about the AES encryption, see:

    http://www.cr0.net:8040/code/crypto/

  Source needed in addition to this file is:

    aes.c
    aes.h

      For those two files, see: http://www.cr0.net:8040/code/crypto/aes/


    sha256.c
    sha256.h

      For those two files, see: http://www.cr0.net:8040/code/crypto/sha256/

    lua.h
    lauxlib.h

      For those two files, see: http://www.lua.org/download.html

  
  To link you also need:

    lua.lib
    lualib.lib

  To compile under Cygwin:
  
    gcc -shared -o aeslib.dll aes.c sha256.c aeslib.c lualib.lib lua.lib
    
*/

/*

  Usage: encrypted_text = encrypt (plaintext, key)
  
*/

static int encrypt (lua_State *L)
  {
  aes_context aes_ctx;
  sha256_context sha_ctx;
  unsigned char digest [32];
  unsigned char IV [16];  /* for cipher block chaining */
  unsigned char * buf;
  size_t offset;
  int i,
      lastn;

  /* get text to encrypt */
  size_t textLength;
  const unsigned char * text = luaL_checklstring (L, 1, &textLength);
    
  /* get key */
  size_t keyLength;
  const unsigned char * key = luaL_checklstring (L, 2, &keyLength);

  /* allocate memory to work in, rounded up to next 16 byte boundary
     plus 16 bytes for the IV */
  buf = (unsigned char *) malloc (textLength + 15 + 16);

  if (!buf)
    luaL_error (L, "not enough memory for encryption");

  /* generate random IV */
  for (i = 0; i < 16; i++)
    IV [i] = rand () & 0xFF;

  /* calculate how many bytes of final block are real data */
  lastn = textLength & 0x0F;

  /* use last 4 bits of IV to store length of final block */
  IV [15] &= 0xF0;
  IV [15] |= lastn;  /* number of bytes in final block */
  
  /* hash supplied key,and IV, to give a key for encryption */
  sha256_starts (&sha_ctx);
  sha256_update (&sha_ctx, IV, 16);
  sha256_update (&sha_ctx, (uint8 *) key, keyLength);
  sha256_finish (&sha_ctx, digest);

  /* use hashed supplied key (digest) for encryption */
  aes_set_key( &aes_ctx, digest, 256);
  
  /* copy initialization vector into output buffer */
  memcpy (buf, IV, 16);
  /* make sure all zero, in case not mod 16 bytes */
  memset (&buf [16], 0, textLength + 15);
  /* copy supplied text into it */
  memcpy (&buf [16], text, textLength);
  
  /* encrypt in blocks of 16 bytes (128 bits) */

  for (offset = 16; offset < (textLength + 16); offset += 16)
    {
    /* xor in the IV for this block */
    for (i = 0; i < 16; i++)
      buf [i + offset] ^= IV [i];
    aes_encrypt (&aes_ctx, &buf [offset], &buf [offset]);
    memcpy (IV, &buf [offset], 16);
    }

  /* push results */
  lua_pushlstring (L, buf, offset);

  free (buf);  /* don't need buffer any more */
  return 1;  /* number of result fields */
  } /* end of encrypt */

/*

  Usage: plaintext = decrypt (encrypted_text, key)
  
*/

static int decrypt (lua_State *L)
  {
  aes_context aes_ctx;
  sha256_context sha_ctx;
  unsigned char digest [32];
  unsigned char IV [16];  /* for cipher block chaining */
  unsigned char tmp [16];
  unsigned char * buf;
  size_t offset;
  int i,
      lastn;

  const unsigned char * text ;
  size_t textLength;

  const unsigned char * key;
  size_t keyLength;

  /* get text to decrypt */
  text = luaL_checklstring (L, 1, &textLength);
  
  if (textLength < 16)
    luaL_error (L, "encrypted data too short, must be at least 16 bytes");
  
  /* encrypted block starts with 16-byte initialization vector */
  memcpy (IV, text, 16);
  textLength -= 16;
  
  /* find how many bytes in final block */
  lastn = IV [15] & 0x0F;
  
  /* get key */
  key = luaL_checklstring (L, 2, &keyLength);

  /* hash supplied key ,and IV, to give a key for decryption */
  sha256_starts (&sha_ctx);
  sha256_update (&sha_ctx, IV, 16 );
  sha256_update (&sha_ctx, (uint8 *) key, keyLength);
  sha256_finish (&sha_ctx, digest);

  /* use hashed supplied key (digest) for decryption */
  aes_set_key( &aes_ctx, digest, 256);

  buf = (unsigned char *) malloc (textLength + 15);

  if (!buf)
    luaL_error (L, "not enough memory for decryption");

  /* make sure all zero, in case not mod 16 bytes */
  memset (buf, 0, textLength + 15);
  /* copy supplied text into it, skipping IV */
  memcpy (buf, &text [16], textLength);

  /* decrypt in blocks of 16 bytes (128 bits) */

  for (offset = 0; offset < textLength; offset += 16)
    {
    memcpy (tmp, &buf [offset], 16); /* this will be the IV next time */
    aes_decrypt (&aes_ctx, &buf [offset], &buf [offset]);
    for ( i = 0; i < 16; i++ )  /* xor in current IV */
      buf [offset + i] ^= IV [i];
    memcpy (IV, tmp, 16);    /* new IV */
    }

  /* trim final length */
  if (lastn)
    offset -= 16 - lastn;
  
  /* push results */
  lua_pushlstring (L, buf, offset);

  free (buf);  /* don't need buffer any more */
  return 1;  /* number of result fields */
  } /* end of decrypt */

#ifdef TEST
static int test (lua_State *L)
  {
  aes_context aes_ctx;
  sha256_context sha_ctx;
  unsigned char digest[32];
  unsigned char buf [16];
  unsigned char result1 [16];
  unsigned char result2 [16];
  
  memset (digest, 0, sizeof (digest));
  memset (buf, 0, sizeof (buf));

  aes_set_key( &aes_ctx, (uint8 *) digest, 256);
  aes_encrypt (&aes_ctx, buf, result1); 
  aes_encrypt (&aes_ctx, result1, result2); 
  
  lua_pushlstring (L, result1, sizeof (result1));
  lua_pushlstring (L, result2, sizeof (result2));
  
  /*
  Results should be: 
    DC95C078A2408989AD48A21492842087
    08C374848C228233C2B34F332BD2E9D3
    
  See "The Design of Rijndael" by Joan Daemen and Vincent Rijmen.
  Test vector results for block length 128, key length 256.
  
  */
  
  return 2;  /* number of result fields */
  } /* end of test */
#endif

/* table of operations */
static const struct luaL_reg aeslib [] = 
  {

  {"encrypt", encrypt},
  {"decrypt", decrypt},

#ifdef TEST
  {"test", test},
#endif

  {NULL, NULL}
  };

/* register library */

LUALIB_API int luaopen_aes(lua_State *L)
  {
  luaL_openlib(L, "aes", aeslib, 0);
  return 1;
  }



We are now ready to start encrypting.

In your script (or command window with scripting prefix) we need to load the DLL (once per session) like this:


assert (loadlib ("aeslib.dll", "luaopen_aes")) ()


The loadlib function returns a function (if possible) from the DLL (the luaopen_aes function) and the final parentheses on that line run that function. This installs two functions:


aes.encrypt
aes.decrypt


In Lua 5.1 (MUSHclient 3.80 onwards) you need to use package.loadlib, instead of loadlib on its own. Also, you need to make sure that the loadlib function has not been removed in the Lua sandbox.

The encrypt and decrypt functions need to use 256-bit keys, so they take the supplied key (the second argument) and use the sha256 function (Secure Hash Algorithm, 256 bit version) to turn whatever string you supply into a 256-bit key.

They then take the text you supply to be encrypted or decrypted, and make a temporary buffer, rounded up in size to the next 16-byte boundary, as the encryption works in blocks of 128 bits (16 times 8).

The functions then iterate over the text, encrypting each 16-byte block, and then returning the result.

An example of use:


x = aes.encrypt ("Nick Gammon", "swordfish")
y = aes.decrypt (x, "swordfish")
print (y)  --> Nick Gammon


Note that since the encryption works in 16-byte blocks, the result will always be a multiple of 16, even if the text isn't. In addition, the encrypted text will be 16 bytes larger, because the Initialization Vector (IV) is stored at the start of it.

The last 4 bits of the initialization vector are used to remember how many bytes in the last block are "real", so that decryption will return the correct length string.

Encryption mode

For added security the encryption is done in cipher-block chaining mode. What this means is that a random 16-byte string is generated at the commencement of encryption. This string is stored at the start of the encrypted block, so it can be used for decryption.

The important part about the random string (the so-called Initialization Vector or IV) is that it is XOR'ed with each block prior to encrypting it. This guarantees that each block will encrypt differently, even if you happen to have a sequence of letters (like "aaaaaaaaaa") in your plain text. Without the cipher-block chaining, it is also possible for someone to reassemble a message by cutting and pasting (in 16-byte blocks) parts from different messages encrypted with the same key.




Disclaimer

Security and encryption are big fields. The methods described above are intended to get you started, if you want to use encryption with MUSHclient (or Lua). You should make enquiries about other aspects of security before relying upon a single encryption algorithm to protect your data or privacy.

Also, the source file given above has not been subject to peer review, there may be errors in the implementation that are not obvious. If you find any please let me know.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #1 on Thu 09 Dec 2004 02:35 AM (UTC)

Amended on Wed 15 Dec 2004 04:35 AM (UTC) by Nick Gammon

Message

The file aeslib.c can be downloaded from http://www.gammon.com.au/files/utils/aeslib.c

The MD5 sum of the file is:


$ md5sum aeslib.c
 db2e8bdf2cf6987c5f72c812d9ca8d50  *aeslib.c

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #2 on Thu 09 Dec 2004 02:47 AM (UTC)

Amended on Thu 27 May 2021 02:44 AM (UTC) by Nick Gammon

Message
Hopefully it goes without saying that the security of any encrypted data is dependent on (other things being equal) the length of the key used to encrypt it.

Although the algorithm above uses a 256-bit key, you will only get the benefit of that if the "passphrase" or key you supply when calling it, has that much "entropy".

There is an easy way of calculating the entropy (ie. the randomness) of a given human-readable key. (This assumes that the key is chosen at random).

Use a scientific calculator, and work out the entropy per character, and multiply by the number of characters.

For example, if you choose a passphrase or key made of lowercase alphabetic characters (a-z) then there are 26 possible combinations.

Use the calculator to work out;


log (combinations) / log (2)


You can use log to the base 10, or natural logs, you will get the same answer.

eg.


log (26) / log (2) = 4.7004


Now multiply by the length of the word you are planning to use. For example, "swordfish" = 9 characters.


entropy = 4.7004 * 9 = 42.30 bits


Thus, using "swordfish" as a password gives you only 42 bits of key, which could probably be broken in under a second.

The other problem with real words, like "swordfish", is that they can be subjected to a dictionary attack. Say you choose any word from a possible 100,000 words that you know.


entropy = log (100000) / log (2) = 16.61


So in fact, "swordfish" is an appallingly bad choice of password. It is equivalent to using a 17-bit key.

Of course, things improve if you use more than one word, but to get a full 256 bits of entropy from using words from a 100,000-word dictionary you need over 15 words!


words needed = 256 / 16.61 = 15.41


Using 256 bits of entropy is probably overkill today, probably around 100 is enough for domestic purposes.

There is an interesting discussion about this on the Diceware page:


http://world.std.com/~reinhold/diceware.html


He describes method of generating keys by rolling dice.

They supply a 7776 word dictionary, designed to fit in with rolling a 6-sided die 5 times per word. (In other words, 6 to the power 5 is 7776). The entropy of that would be:


entropy = log (7776) / log (2) = 12.9248


Thus you would need only about 8 such words to get 100 bits of entropy.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #3 on Thu 09 Dec 2004 03:12 AM (UTC)

Amended on Thu 09 Dec 2004 03:14 AM (UTC) by Nick Gammon

Message
If you are using Lua you can make an "entropy" function to save a bit of work:


function entropy (x) return (math.log (x) / math.log (2)) end


Now you can test things out with a simple call. For example, using a 15-digit number (where each number can have 10 possibilites) ...


print (entropy (10) * 15) --> 49.82892142331


Similarly for the earlier example of 100,000 words:


print (entropy (100000)) --> 16.609640474437


Or, looking at it another way ... How many digits do I need to have 256 bits of entropy, if I use a simple numeric passphrase?


print (256 / entropy (10)) --> 77.063678889979


OK, you need a 77-digit number. Hope your memory is better than mine at remembering it. ;)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #4 on Wed 15 Dec 2004 04:24 AM (UTC)

Amended on Mon 02 Oct 2006 08:54 AM (UTC) by Nick Gammon

Message
A few more points:


  • Although this library was written for MUSHclient, there is no particular reason it couldn't be used for general encryption by anyone using Lua.

  • You may want to consider adding a message sequence, or a date/time stamp, inside any encrypted message, to guard against a "replay attack". That is, an attack where someone stores an old message from/to you and resends it, thus fooling you into thinking it is a recent one.

  • You may also want to add a "message digest" such as a hash of the complete unencrypted message, into the body of the message. This hash is a guarantee that the message appears in its entirety. Without it, it is possible for someone to truncate your message, possibly altering the sense of it.

  • Suggested key length (entropy). The Diceware page mentioned above quotes:

    Quote:

    In their February 1996 report, "Minimal Key Lengths for Symmetric Ciphers to Provide Adequate Commercial Security" a group of cryptography and computer security experts -- Matt Blaze, Whitfield Diffie, Ronald Rivest, Bruce Schneier, Tsutomo Shimomura, Eric Thompson, and Michael Weiner -- stated:

    "To provide adequate protection against the most serious threats... keys used to protect data today should be at least 75 bits long. To protect information adequately for the next 20 years ... keys in newly-deployed systems should be at least 90 bits long."


  • This page describes symmetrical encryption, where both the sender and receiver of a message have the same key. Securely exchanging keys is a big field in itself, and one that is not directly addressed here. One possible method of exchanging a key is to physically meet and exchange keys. If this is not practical, you could generate a random key (for example, using Diceware) and then exchange that key using public/private key encryption, such as PGP (Pretty Good Privacy) or GPG (Gnu Privacy Guard).

    Also see the new post further down about exchanging keys using the Diffie-Hellman protocol.

  • I mentioned earlier that for security you need a long key. Obviously it also needs to be randomly-generated. A long key consisting of 100 times the letter "a" will not be secure. Also pseudo-random numbers (such as computer-generated random numbers) will not be secure. Throwing dice is one approach. Picking words out of a book at random is another. You can buy inexpensive Bingo games from toy shops. These can be used to randomly generate a number in the range 1 to 90 (or whatever number the game supplies). If it generates 90 numbers (ie. each with an entropy of 6.49) then you would only need around 15 such numbers to get 100 bits of entropy.

    This compares favourably to rolling dice. Each die roll would have 2.58 bits of entropy compared to 6.49 per bingo ball. Thus to get, say, 100 bits of entropy you need 39 dice rolls, compared to 16 Bingo balls. That's somewhat less tedium, if you are going to do it often.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #5 on Wed 15 Dec 2004 05:21 AM (UTC)
Message

Below is a picture of an example of a Bingo rolling game. This lets you generate numbers randomly in the range 1 to 90.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #6 on Sun 19 Dec 2004 10:21 AM (UTC)
Message
There are random number generators you can download that generate purely random numbers (you can check them with ent), or you can go to www.random.org and get a live random stream.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #7 on Sun 19 Dec 2004 07:18 PM (UTC)
Message
What do you mean "purely" random. By definition almost every generator must follow some mathematical sequence. The only things that are going to be purely random are randomly-occuring things in nature like atomic decay, or thermal noise in a resistor. You can buy gadgets that measure those, but they aren't cheap. How many people do you know with a geiger counter, for example? And there is the question of interfacing it with the PC, in a way that doesn't corrupt the data stream

As for downloading, yes there may be sites that connect to geiger counters that measure atomic decay but downloading your random numbers from the Net is hardly secure, even if may be random. What if someone is logging every byte that enters your PC for example?

Flipping a coin, rolling a die, or the bingo machine (I suggest) are about the only ways of easily generating true randomness that doesn't rely upon something else.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #8 on Mon 20 Dec 2004 01:12 PM (UTC)
Message
I think those programs work by measuring the time it takes for it to access random locations in the memory. I don't remember exactly, but it really is random. See http://comscire.com/FAQ/ for details.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #9 on Mon 20 Dec 2004 07:19 PM (UTC)
Message
I would have thought that the time to access memory was fairly predictable. This sentence on that page makes me worry a bit:

Quote:

Q. Can I use the [product] as a random event generator (REG) for micro-PK, DMMI or other parapsychological experiments?

A. Yes - The [product], which is a true random number generator, will respond to operator intention like other REG's.


So, it's a random number generator that is truly random, except it is influenced by what you are thinking?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #10 on Mon 20 Dec 2004 09:01 PM (UTC)
Message
Well, yes, as much as any other random generator (or at least they think so). Don't take my word for it, download it and use ent to check it. The chi squared distribution of the bitstream at least was 50 and all the other figures checked out too...

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by Nick Gammon   Australia  (23,072 posts)  Bio   Forum Administrator
Date Reply #11 on Mon 20 Dec 2004 09:59 PM (UTC)
Message
I am sure that these generators pass the various statistical tests. However with (say) the Marsenne Twister (recently added to MUSHclient) you can probably get very good statistical results. However it is still deterministic. If I guess your seed, I can reproduce your sequence exactly. Say you do what a lot of texts recommend, and seed with the system time. Well, the time of day is hardly a secret. Some systems have been hacked into by people knowing the random-number generator was seeded by the time, thus greatly reducing the set of possible sequences they might use (knowing the time the message originated).

The pseudo-sequences may "look random" but they're not. They are the output of a computer program.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #12 on Mon 20 Dec 2004 10:23 PM (UTC)
Message
This program doesn't seed an algorithm and then retrieve the sequence, it's not a PRNG. And the chi square distribution test is very hard to pass, the Mersenne Twister would probably fall on 10 or so. I'm trying to find a program to test it.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #13 on Mon 20 Dec 2004 10:32 PM (UTC)
Message
Quote:
So, it's a random number generator that is truly random, except it is influenced by what you are thinking?
Funny thing, but I believe that's one of the basic premises of quantum physics anyhow... :) If you look through their site they do make a lot of mumbling about quantum physics. I'm not sure I buy it, but hey...

By the way, I'm not sure that accessing memory really is in deterministic time. Probably nearly deterministic, but not quite - especially according to quantum mechanics and all that bla bla. Like I said I'm not sure I buy it but there might be some truth to it...

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Poromenos   Greece  (1,037 posts)  Bio
Date Reply #14 on Mon 20 Dec 2004 10:49 PM (UTC)

Amended on Mon 20 Dec 2004 10:50 PM (UTC) by Poromenos

Message
The Mersenne Twister output analysis:

Entropy = 7.997857 bits per byte.

Optimum compression would reduce the size
of this 20078025 byte file by 0 percent.

Chi square distribution for 20078025 samples is 76829.54, and randomly
would exceed this value 0.01 percent of the times.

Arithmetic mean value of data bytes is 127.0523 (127.5 = random).
Monte Carlo value for Pi is 3.150064085 (error 0.27 percent).
Serial correlation coefficient is 0.009176 (totally uncorrelated = 0.0).


This basically means that the data is quite deterministic. I had done the same with the other program some time ago and I got a 50% chi square distribution.

Vidi, Vici, Veni.
http://porocrom.poromenos.org/ Read it!
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


129,033 views.

This is page 1, subject is 3 pages long: 1 2  3  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.