wordgenerator.java

来自「Java mulitplayer strategy game. Adaptati」· Java 代码 · 共 245 行

JAVA
245
字号
/*
 * WordGenerator.java
 *
 * Created on 11 pa焏ziernik 2005, 00:40
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package net.sf.jawp.util;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.Random;

/**
 * Word/Password generator.
 * original source code taken from:
 *
 * http://www.multicians.org/thvv/gpw.html
 *
 * Sources were slightly adopted to use inside server application.
 * Core algorithm remains unchanged.
 * 
 * 
 * 
 * @author jarek
 */

public class WordGenerator
{
	
	
	private static final Gpw GPW = new Gpw();
	
	public static String generateWord( final Random generator, final int size)
	{
		return WordGenerator.GPW.generate( generator, 1, size)[0];
		
	}
	
	public static void main(final String[] args)
	{
		System.out.println(WordGenerator.generateWord( new Random(), 10));
		System.out.println(WordGenerator.generateWord( new Random(), 10));
		System.out.println(WordGenerator.generateWord( new Random(), 10));
		System.out.println(WordGenerator.generateWord( new Random(), 10));
	}
	
	
	
}

final class Gpw
{
	private static final  String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
	
	private static final GpwData DATA =  new GpwData();
	
	
	
	
	/**
	 *  This thing is hopeless.
	 *  Lesson 34 - if You find comment like:  "//for c1" at the end of loop 
	 *  You know it is time to run. 
	 *  
	 * @param ran
	 * @param npw
	 * @param pwl
	 * @return
	 */
	public String[] generate(final Random ran, final int npw, final int pwl)
	{

		StringBuffer password = null;
		final String[] results = new String[npw];
		
		// Pick a random starting point.
		for (int pwnum = 0; pwnum < npw; pwnum++)
		{
			password = new StringBuffer(pwl);
			final double pik = ran.nextDouble(); // random number [0,1]
			final long ranno = (long)(pik * DATA.getSigma()); // weight by sum of frequencies
			
			appendThree( ranno, password);
			
			// Now do a random walk.
			
			sumPass(ran, pwl, password);
			results[pwnum] = password.toString();
			
		} // for pwnum
		return results;
	} // generate()




	private void sumPass(final Random ran, final int pwl, final StringBuffer password)
	{
		int nchar = 3;
		double pik;
		long ranno;
		while (nchar < pwl)
		{
			int c1, c2;
			c1 = ALPHABET.indexOf(password.charAt(nchar - 2));
			c2 = ALPHABET.indexOf(password.charAt(nchar - 1));
			long sum = 0;
			for (int c3 = 0; c3 < 26; c3++)
			{
				sum += DATA.get(c1, c2, c3);
			}
			if (sum == 0)
			{
				break;	// exit while loop
			}
			pik = ran.nextDouble();
			ranno = (long)(pik * sum);
			sum = 0;
			for (int c3 = 0; c3 < 26; c3++)
			{
				sum += DATA.get(c1, c2, c3);
				if (sum > ranno)
				{
					password.append(ALPHABET.charAt(c3));
					c3 = 26; // break for loop
				} // if sum
			} // for c3
			nchar++;
		} // while nchar
	}




	private void appendThree( final long ranno, final StringBuffer password)
	{
		long sum = 0;
		for (int c1 = 0; c1 < 26; c1++)
		{
			for (int c2 = 0; c2 < 26; c2++)
			{
				for (int c3 = 0; c3 < 26; c3++)
				{
					sum += DATA.get(c1, c2, c3);
					if (sum > ranno)
					{
						password.append(ALPHABET.charAt(c1));
						password.append(ALPHABET.charAt(c2));
						password.append(ALPHABET.charAt(c3));
						c1 = 26; // Found start. Break all 3 loops.
						c2 = 26;
						c3 = 26;
					} // if sum
				} // for c3
			} // for c2
		} // for c1
	}
	
} // GpwWindow

// ================================================================

class GpwData
{
	private static final Log LOG = Log.getLog(GpwData.class);
	
	private static short[][][] tris = null;
	private static long[] sigma = null; // 125729
	
	GpwData()
	{
		int c1, c2, c3;
		tris = new short[26][26][26];
		sigma = new long[1];
	//	GpwDataInit1.fill(this); // Break into two classes for NS 4.0
	//	GpwDataInit2.fill(this); // .. its Java 1.1 barfs on methods > 65K
		restoreTris();
		for (c1 = 0; c1 < 26; c1++)
		{
			for (c2 = 0; c2 < 26; c2++)
			{
				for (c3 = 0; c3 < 26; c3++)
				{
					sigma[0] += (long) tris[c1][c2][c3];
				} // for c3
			} // for c2
		} // for c1
	} // constructor
	
	/* no longer needed
	 * private void storeTris()
	{
		try
		{
			final FileOutputStream file = new FileOutputStream("tris.dat",false);
			final ObjectOutputStream out = new ObjectOutputStream(file);
			out.writeObject( tris );
			out.close();
			file.close();
		}
		catch (final IOException ioe)
		{
			LOG.error(ioe);
		}
	}*/
	
	private void restoreTris()
	{
		try
		{
			final InputStream input = getClass().getResourceAsStream("/data/tris.dat");
			final ObjectInputStream oinput = new ObjectInputStream(input);
			tris = (short[][][])oinput.readObject();
			oinput.close();
			input.close();
		}
		catch (final Exception ioe)
		{
			LOG.error(ioe);
		}
	}
	
	void set(final int x1, final int x2, final int x3, final short v)
	{
		tris[x1][x2][x3] = v;
	} // set()
	
	long get(final int x1, final int x2, final int x3)
	{
		return (long) tris[x1][x2][x3];
	} // get()
	
	long getSigma()
	{
		return sigma[0];
	} // get()
	
} // GpwData


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?