* Utils: Drop unused BufferedRandomSource, PooledRandomSource,

EepGetScheduler, EepPost and HTTPSendData, moved to i2p.scripts
This commit is contained in:
zzz
2012-08-16 18:25:49 +00:00
parent 3fe092d788
commit a900511d5e
5 changed files with 0 additions and 857 deletions

View File

@@ -1,236 +0,0 @@
package net.i2p.util;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2005 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.I2PAppContext;
/**
* Allocate data out of a large buffer of data, rather than the PRNG's
* (likely) small buffer to reduce the frequency of prng recalcs (though
* the recalcs are now more time consuming).
*
* @deprecated Unused! See FortunaRandomSource
*
*/
public class BufferedRandomSource extends RandomSource {
private byte _buffer[];
private int _nextByte;
private int _nextBit;
private static volatile long _reseeds;
private static final int DEFAULT_BUFFER_SIZE = 256*1024;
public BufferedRandomSource(I2PAppContext context) {
this(context, DEFAULT_BUFFER_SIZE);
}
public BufferedRandomSource(I2PAppContext context, int bufferSize) {
super(context);
context.statManager().createRateStat("prng.reseedCount", "How many times the prng has been reseeded", "Encryption", new long[] { 60*1000, 10*60*1000, 60*60*1000 } );
_buffer = new byte[bufferSize];
refillBuffer();
// stagger reseeding
_nextByte = ((int)_reseeds-1) * 16 * 1024;
}
private final void refillBuffer() {
long before = System.currentTimeMillis();
doRefillBuffer();
long duration = System.currentTimeMillis() - before;
if ( (_reseeds % 1) == 0)
_context.statManager().addRateData("prng.reseedCount", _reseeds, duration);
}
private synchronized final void doRefillBuffer() {
super.nextBytes(_buffer);
_nextByte = 0;
_nextBit = 0;
_reseeds++;
}
private static final byte GOBBLE_MASK[] = { 0x0, // 0 bits
0x1, // 1 bit
0x3, // 2 bits
0x7, // 3 bits
0xF, // 4 bits
0x1F, // 5 bits
0x3F, // 6 bits
0x7F, // 7 bits
(byte)0xFF // 8 bits
};
private synchronized final long nextBits(int numBits) {
if (false) {
long rv = 0;
for (int curBit = 0; curBit < numBits; curBit++) {
if (_nextBit >= 8) {
_nextBit = 0;
_nextByte++;
}
if (_nextByte >= _buffer.length)
refillBuffer();
rv += (_buffer[_nextByte] << curBit);
_nextBit++;
/*
int avail = 8 - _nextBit;
// this is not correct! (or is it?)
rv += (_buffer[_nextByte] << 8 - avail);
_nextBit += avail;
numBits -= avail;
if (_nextBit >= 8) {
_nextBit = 0;
_nextByte++;
}
*/
}
return rv;
} else {
long rv = 0;
int curBit = 0;
while (curBit < numBits) {
if (_nextBit >= 8) {
_nextBit = 0;
_nextByte++;
}
if (_nextByte >= _buffer.length)
refillBuffer();
int gobbleBits = 8 - _nextBit;
int want = numBits - curBit;
if (gobbleBits > want)
gobbleBits = want;
curBit += gobbleBits;
int shift = 8 - _nextBit - gobbleBits;
int c = (_buffer[_nextByte] & (GOBBLE_MASK[gobbleBits] << shift));
rv += ((c >>> shift) << (curBit-gobbleBits));
_nextBit += gobbleBits;
}
return rv;
}
}
@Override
public synchronized final void nextBytes(byte buf[]) {
int outOffset = 0;
while (outOffset < buf.length) {
int availableBytes = _buffer.length - _nextByte - (_nextBit != 0 ? 1 : 0);
if (availableBytes <= 0)
refillBuffer();
int start = _buffer.length - availableBytes;
int writeSize = Math.min(buf.length - outOffset, availableBytes);
System.arraycopy(_buffer, start, buf, outOffset, writeSize);
outOffset += writeSize;
_nextByte += writeSize;
_nextBit = 0;
}
}
@Override
public final int nextInt(int n) {
if (n <= 0) return 0;
int val = ((int)nextBits(countBits(n))) % n;
if (val < 0)
return 0 - val;
else
return val;
}
@Override
public final int nextInt() { return nextInt(Integer.MAX_VALUE); }
/**
* Like the modified nextInt, nextLong(n) returns a random number from 0 through n,
* including 0, excluding n.
*/
@Override
public final long nextLong(long n) {
if (n <= 0) return 0;
long val = nextBits(countBits(n)) % n;
if (val < 0)
return 0 - val;
else
return val;
}
@Override
public final long nextLong() { return nextLong(Long.MAX_VALUE); }
static final int countBits(long val) {
int rv = 0;
while (val > Integer.MAX_VALUE) {
rv += 31;
val >>>= 31;
}
while (val > 0) {
rv++;
val >>= 1;
}
return rv;
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public final boolean nextBoolean() {
return nextBits(1) != 0;
}
private static final double DOUBLE_DENOMENATOR = (1L << 53);
/** defined per javadoc ( ((nextBits(26)<<27) + nextBits(27)) / (1 << 53)) */
@Override
public final double nextDouble() {
long top = ((nextBits(26) << 27) + nextBits(27));
return top / DOUBLE_DENOMENATOR;
}
private static final float FLOAT_DENOMENATOR = (1 << 24);
/** defined per javadoc (nextBits(24) / ((float)(1 << 24)) ) */
@Override
public float nextFloat() {
long top = nextBits(24);
return top / FLOAT_DENOMENATOR;
}
@Override
public double nextGaussian() {
// bah, unbuffered
return super.nextGaussian();
}
/*****
public static void main(String args[]) {
for (int i = 0; i < 16; i++)
test();
}
private static void test() {
I2PAppContext ctx = I2PAppContext.getGlobalContext();
byte data[] = new byte[16*1024];
for (int i = 0; i < data.length; i += 4) {
long l = ctx.random().nextLong();
if (l < 0) l = 0 - l;
DataHelper.toLong(data, i, 4, l);
}
byte compressed[] = DataHelper.compress(data);
System.out.println("Data: " + data.length + "/" + compressed.length + ": " + toString(data));
}
private static final String toString(byte data[]) {
StringBuilder buf = new StringBuilder(data.length * 9);
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < 8; j++) {
if ((data[i] & (1 << j)) != 0)
buf.append('1');
else
buf.append('0');
}
buf.append(' ');
}
return buf.toString();
}
*****/
}

View File

@@ -1,89 +0,0 @@
package net.i2p.util;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import net.i2p.I2PAppContext;
/**
* @deprecated unused a webapp version would be nice though
*/
public class EepGetScheduler implements EepGet.StatusListener {
private I2PAppContext _context;
private List _urls;
private List _localFiles;
private String _proxyHost;
private int _proxyPort;
private int _curURL;
private EepGet.StatusListener _listener;
public EepGetScheduler(I2PAppContext ctx, List urls, List localFiles, String proxyHost, int proxyPort, EepGet.StatusListener lsnr) {
_context = ctx;
_urls = urls;
_localFiles = localFiles;
_proxyHost = proxyHost;
_proxyPort = proxyPort;
_curURL = -1;
_listener = lsnr;
}
public void fetch() {
I2PThread t = new I2PThread(new Runnable() {
public void run() {
fetchNext();
}
}, "EepGetScheduler");
t.setDaemon(true);
t.start();
}
public void fetch(boolean shouldBlock) {
//Checking for a valid index is done in fetchNext, so we don't have to worry about it.
if (shouldBlock) {
while (_curURL < _urls.size())
fetchNext();
} else {
fetch();
}
}
private void fetchNext() {
_curURL++;
if (_curURL >= _urls.size()) return;
String url = (String)_urls.get(_curURL);
String out = EepGet.suggestName(url);
if ( (_localFiles != null) && (_localFiles.size() > _curURL) ) {
File f = (File)_localFiles.get(_curURL);
out = f.getAbsolutePath();
} else {
if (_localFiles == null)
_localFiles = new ArrayList(_urls.size());
_localFiles.add(new File(out));
}
EepGet get = new EepGet(_context, ((_proxyHost != null) && (_proxyPort > 0)), _proxyHost, _proxyPort, 0, out, url);
get.addStatusListener(this);
get.fetch();
}
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) {
_listener.attemptFailed(url, bytesTransferred, bytesRemaining, currentAttempt, numRetries, cause);
}
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {
_listener.bytesTransferred(alreadyTransferred, currentWrite, bytesTransferred, bytesRemaining, url);
}
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {
_listener.transferComplete(alreadyTransferred, bytesTransferred, bytesRemaining, url, outputFile, notModified);
fetchNext();
}
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
_listener.transferFailed(url, bytesTransferred, bytesRemaining, currentAttempt);
fetchNext();
}
public void attempting(String url) { _listener.attempting(url); }
public void headerReceived(String url, int attemptNum, String key, String val) {}
}

View File

@@ -1,221 +0,0 @@
package net.i2p.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import net.i2p.I2PAppContext;
/**
* Simple helper for uploading files and such via HTTP POST (rfc 1867)
*
* @deprecated unused
*/
public class EepPost {
private Log _log;
private static final String CRLF = "\r\n";
public EepPost() {
this(I2PAppContext.getGlobalContext());
}
public EepPost(I2PAppContext ctx) {
_log = ctx.logManager().getLog(EepPost.class);
}
/*****
public static void main(String args[]) {
EepPost e = new EepPost();
Map fields = new HashMap();
fields.put("key", "value");
fields.put("key1", "value1");
fields.put("key2", "value2");
fields.put("blogpost0", new File("/home/i2p/1.snd"));
fields.put("blogpost1", new File("/home/i2p/2.snd"));
fields.put("blogpost2", new File("/home/i2p/2.snd"));
fields.put("blogpost3", new File("/home/i2p/2.snd"));
fields.put("blogpost4", new File("/home/i2p/2.snd"));
fields.put("blogpost5", new File("/home/i2p/2.snd"));
e.postFiles("http://localhost:7653/import.jsp", null, -1, fields, null);
//e.postFiles("http://localhost/cgi-bin/read.pl", null, -1, fields, null);
//e.postFiles("http://localhost:2001/import.jsp", null, -1, fields, null);
}
*****/
/**
* Submit an HTTP POST to the given URL (using the proxy if specified),
* uploading the given fields. If the field's value is a File object, then
* that file is uploaded, and if the field's value is a String object, the
* value is posted for that particular field. Multiple values for one
* field name is not currently supported.
*
*/
public void postFiles(String url, String proxyHost, int proxyPort, Map fields, Runnable onCompletion) {
I2PThread postThread = new I2PThread(new Runner(url, proxyHost, proxyPort, fields, onCompletion));
postThread.start();
}
private class Runner implements Runnable {
private String _url;
private String _proxyHost;
private int _proxyPort;
private Map _fields;
private Runnable _onCompletion;
public Runner(String url, String proxy, int port, Map fields, Runnable onCompletion) {
_url = url;
_proxyHost = proxy;
_proxyPort = port;
_fields = fields;
_onCompletion = onCompletion;
}
public void run() {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Running the post task");
Socket s = null;
try {
URL u = new URL(_url);
String h = u.getHost();
int p = u.getPort();
if (p <= 0)
p = 80;
String path = u.getPath();
boolean isProxy = true;
if ( (_proxyHost == null) || (_proxyPort <= 0) ) {
isProxy = false;
_proxyHost = h;
_proxyPort = p;
}
if (_log.shouldLog(Log.DEBUG)) _log.debug("Connecting to the server/proxy...");
s = new Socket(_proxyHost, _proxyPort);
if (_log.shouldLog(Log.DEBUG)) _log.debug("Connected");
OutputStream out = s.getOutputStream();
String sep = getSeparator();
long length = calcContentLength(sep, _fields);
if (_log.shouldLog(Log.DEBUG)) _log.debug("Separator: " + sep + " content length: " + length);
String header = getHeader(isProxy, path, h, p, sep, length);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Header: \n" + header);
out.write(header.getBytes());
out.flush();
if (false) {
out.write(("--" + sep + CRLF + "content-disposition: form-data; name=\"field1\"" + CRLF + CRLF + "Stuff goes here" + CRLF + "--" + sep + "--" + CRLF).getBytes());
} else {
sendFields(out, sep, _fields);
}
out.flush();
if (_log.shouldLog(Log.DEBUG)) {
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while ( (line = in.readLine()) != null) {
_log.debug("recv: [" + line + "]");
}
}
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (s != null) try { s.close(); } catch (IOException ioe) {}
if (_onCompletion != null)
_onCompletion.run();
}
}
}
private long calcContentLength(String sep, Map fields) {
long len = 0;
for (Iterator iter = fields.keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next();
Object val = fields.get(key);
if (val instanceof File) {
File f = (File)val;
len += ("--" + sep + CRLF + "Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + f.getName() + "\"" + CRLF).length();
//len += ("Content-length: " + f.length() + "\n").length();
len += ("Content-Type: application/octet-stream" + CRLF + CRLF).length();
len += f.length();
len += CRLF.length(); // nl
} else {
len += ("--" + sep + CRLF + "Content-Disposition: form-data; name=\"" + key + "\"" + CRLF + CRLF).length();
len += val.toString().length();
len += CRLF.length(); // nl
}
}
len += 2 + sep.length() + 2 + CRLF.length(); //2 + sep.length() + 2;
//len += 2;
return len;
}
private void sendFields(OutputStream out, String separator, Map fields) throws IOException {
for (Iterator iter = fields.keySet().iterator(); iter.hasNext(); ) {
String field = (String)iter.next();
Object val = fields.get(field);
if (val instanceof File)
sendFile(out, separator, field, (File)val);
else
sendField(out, separator, field, val.toString());
}
out.write(("--" + separator + "--" + CRLF).getBytes());
}
private void sendFile(OutputStream out, String separator, String field, File file) throws IOException {
//long len = file.length();
out.write(("--" + separator + CRLF).getBytes());
out.write(("Content-Disposition: form-data; name=\"" + field + "\"; filename=\"" + file.getName() + "\"" + CRLF).getBytes());
//out.write(("Content-length: " + len + "\n").getBytes());
out.write(("Content-Type: application/octet-stream" + CRLF + CRLF).getBytes());
FileInputStream in = new FileInputStream(file);
byte buf[] = new byte[1024];
int read = -1;
while ( (read = in.read(buf)) != -1)
out.write(buf, 0, read);
out.write(CRLF.getBytes());
in.close();
}
private void sendField(OutputStream out, String separator, String field, String val) throws IOException {
out.write(("--" + separator + CRLF).getBytes());
out.write(("Content-Disposition: form-data; name=\"" + field + "\"" + CRLF + CRLF).getBytes());
out.write(val.getBytes());
out.write(CRLF.getBytes());
}
private String getHeader(boolean isProxy, String path, String host, int port, String separator, long length) {
StringBuilder buf = new StringBuilder(512);
buf.append("POST ");
if (isProxy) {
buf.append("http://").append(host);
if (port != 80)
buf.append(":").append(port);
}
buf.append(path);
buf.append(" HTTP/1.1" + CRLF);
buf.append("Host: ").append(host);
if (port != 80)
buf.append(":").append(port);
buf.append(CRLF);
buf.append("Connection: close" + CRLF);
buf.append("Content-length: ").append(length).append(CRLF);
buf.append("Content-type: multipart/form-data, boundary=").append(separator);
buf.append(CRLF);
buf.append(CRLF);
return buf.toString();
}
private String getSeparator() {
//if (false)
// return "ABCDEFG";
//if (false)
// return "------------------------" + new java.util.Random().nextLong();
byte separator[] = new byte[32]; // 2^-128 chance of this being a problem
I2PAppContext.getGlobalContext().random().nextBytes(separator);
StringBuilder sep = new StringBuilder(48);
for (int i = 0; i < separator.length; i++)
sep.append((char)('a' + (separator[i]&0x0F))).append((char)('a' + ((separator[i] >>> 4) & 0x0F)));
return sep.toString();
}
}

View File

@@ -1,92 +0,0 @@
package net.i2p.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPOutputStream;
/**
* Simple helper class to submit data via HTTP Post
*
* @deprecated unused
*/
public class HTTPSendData {
private final static Log _log = new Log(HTTPSendData.class);
/**
* Submit an HTTP post to the given url, sending the data specified
*
* @param url url to post to
* @param length number of bytes in the dataToSend to, er, send
* @param dataToSend stream of bytes to be sent
* @return true if the data was posted successfully
*/
public static boolean postData(String url, long length, InputStream dataToSend) {
try {
URL rurl = new URL(url);
return postData(rurl, length, dataToSend);
} catch (MalformedURLException mue) {
return false;
}
}
/**
* Submit an HTTP post to the given url, sending the data specified
*
* @param url url to post to
* @param length number of bytes in the dataToSend to, er, send
* @param dataToSend stream of bytes to be sent
*/
public static boolean postData(URL url, long length, InputStream dataToSend) {
try {
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", "" + length);
OutputStream out = con.getOutputStream();
byte buf[] = new byte[1 * 1024];
int read;
long sent = 0;
GZIPOutputStream zipOut = new GZIPOutputStream(out);
while ((read = dataToSend.read(buf)) != -1) {
zipOut.write(buf, 0, read);
sent += read;
if (sent >= length) break;
}
zipOut.flush();
zipOut.finish();
zipOut.close();
out.close();
int rv = con.getResponseCode();
_log.debug("Posted " + sent + " bytes: " + rv);
return length == sent;
} catch (IOException ioe) {
_log.error("Error posting the data", ioe);
return false;
}
}
/****
public static void main(String args[]) {
byte data[] = new byte[4096];
for (int i = 0; i < data.length; i++)
data[i] = (byte) ((i % 26) + 'a');
boolean sent = HTTPSendData.postData("http://dev.i2p.net/cgi-bin/submitMessageHistory", data.length,
new ByteArrayInputStream(data));
_log.debug("Sent? " + sent);
try {
Thread.sleep(2000);
} catch (InterruptedException ie) { // nop
}
}
****/
}

View File

@@ -1,219 +0,0 @@
package net.i2p.util;
/*
* free (adj.): unencumbered; not under the control of others
* Written by jrandom in 2005 and released into the public domain
* with no warranty of any kind, either expressed or implied.
* It probably won't make your computer catch on fire, or eat
* your children, but it might. Use at your own risk.
*
*/
import net.i2p.I2PAppContext;
import net.i2p.crypto.EntropyHarvester;
import net.i2p.data.Base64;
/**
* Maintain a set of PRNGs to feed the apps
*
* @deprecated Unused! See FortunaRandomSource
*
*/
public class PooledRandomSource extends RandomSource {
private Log _log;
protected RandomSource _pool[];
protected volatile int _nextPool;
public static final int POOL_SIZE = 16;
/**
* How much random data will we precalculate and feed from (as opposed to on demand
* reseeding, etc). If this is not set, a default will be used (4MB), or if it is
* set to 0, no buffer will be used, otherwise the amount specified will be allocated
* across the pooled PRNGs.
*
*/
public static final String PROP_BUFFER_SIZE = "i2p.prng.totalBufferSizeKB";
public PooledRandomSource(I2PAppContext context) {
super(context);
_log = context.logManager().getLog(PooledRandomSource.class);
initializePool(context);
}
protected void initializePool(I2PAppContext context) {
_pool = new RandomSource[POOL_SIZE];
String totalSizeProp = context.getProperty(PROP_BUFFER_SIZE);
int totalSize = -1;
if (totalSizeProp != null) {
try {
totalSize = Integer.parseInt(totalSizeProp);
} catch (NumberFormatException nfe) {
totalSize = -1;
}
}
byte buf[] = new byte[1024];
initSeed(buf);
for (int i = 0; i < POOL_SIZE; i++) {
if (totalSize < 0)
_pool[i] = new BufferedRandomSource(context);
else if (totalSize > 0)
_pool[i] = new BufferedRandomSource(context, (totalSize*1024) / POOL_SIZE);
else
_pool[i] = new RandomSource(context);
_pool[i].setSeed(buf);
if (i > 0) {
_pool[i-1].nextBytes(buf);
_pool[i].setSeed(buf);
}
}
_pool[0].nextBytes(buf);
System.out.println("seeded and initialized: " + Base64.encode(buf));
_nextPool = 0;
}
private final RandomSource pickPRNG() {
// how much more explicit can we get?
int cur = _nextPool;
cur = cur % POOL_SIZE;
RandomSource rv = _pool[cur];
cur++;
cur = cur % POOL_SIZE;
_nextPool = cur;
return rv;
}
/**
* According to the java docs (http://java.sun.com/j2se/1.4.1/docs/api/java/util/Random.html#nextInt(int))
* nextInt(n) should return a number between 0 and n (including 0 and excluding n). However, their pseudocode,
* as well as sun's, kaffe's, and classpath's implementation INCLUDES NEGATIVE VALUES.
* WTF. Ok, so we're going to have it return between 0 and n (including 0, excluding n), since
* thats what it has been used for.
*
*/
@Override
public int nextInt(int n) {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextInt(n);
}
}
/**
* Like the modified nextInt, nextLong(n) returns a random number from 0 through n,
* including 0, excluding n.
*/
@Override
public long nextLong(long n) {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextLong(n);
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public boolean nextBoolean() {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextBoolean();
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public void nextBytes(byte buf[]) {
RandomSource prng = pickPRNG();
synchronized (prng) {
prng.nextBytes(buf);
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public double nextDouble() {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextDouble();
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public float nextFloat() {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextFloat();
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public double nextGaussian() {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextGaussian();
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public int nextInt() {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextInt();
}
}
/**
* override as synchronized, for those JVMs that don't always pull via
* nextBytes (cough ibm)
*/
@Override
public long nextLong() {
RandomSource prng = pickPRNG();
synchronized (prng) {
return prng.nextLong();
}
}
@Override
public EntropyHarvester harvester() {
RandomSource prng = pickPRNG();
return prng.harvester();
}
/*****
public static void main(String args[]) {
//PooledRandomSource prng = new PooledRandomSource(I2PAppContext.getGlobalContext());
long start = System.currentTimeMillis();
RandomSource prng = I2PAppContext.getGlobalContext().random();
long created = System.currentTimeMillis();
System.out.println("prng type: " + prng.getClass().getName());
int size = 8*1024*1024;
try {
java.io.FileOutputStream out = new java.io.FileOutputStream("random.file");
for (int i = 0; i < size; i++) {
out.write(prng.nextInt());
}
out.close();
} catch (Exception e) { e.printStackTrace(); }
long done = System.currentTimeMillis();
System.out.println("Written to random.file: create took " + (created-start) + ", generate took " + (done-created));
prng.saveSeed();
}
*****/
}