Android Open Source - passwordcard-android Password Card






From Project

Back to project page passwordcard-android.

License

The source code is released under:

GNU General Public License

If you think the Android project passwordcard-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * This file is part of PasswordCard./*from www  .j  a va  2s  .  c om*/
 *
 * PasswordCard is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PasswordCard is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PasswordCard.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright  2010 pepsoft.org.
 */

package org.pepsoft.passwordcard;

import java.security.SecureRandom;
import java.util.Random;

import org.pepsoft.util.Math;

/**
 * A uniquely numbered PasswordCard.
 * 
 * @author pepsoft.org
 */
public class PasswordCard {
    /**
     * Create a new PasswordCard with a specific number and specific options.
     *
     * @param number The serial number or seed of the card.
     * @param digitArea Whether to include an area containing only digits.
     * @param includeSymbols Whether to include symbols.
     */
    public PasswordCard(long number, boolean digitArea, boolean includeSymbols) {
        this.number = number;
        this.digitArea = digitArea;
        this.includeSymbols = includeSymbols;
    }

    /**
     * Get the card serial number or seed.
     *
     * @return The card serial number or seed.
     */
    public long getNumber() {
        return number;
    }

    /**
     * Get the contents of the card as a two dimensional array of characters.
     *
     * @return The contents of the card.
     */
    public synchronized char[][] getGrid() {
        if (grid == null) {
            generateGrid();
        }
        return grid;
    }

    /**
     * Get the contents of the card as a string containing multiple lines, using
     * the specified EOL sequence. Each line except the header will have a line
     * number (starting with 1) appended.
     *
     * @param eol The EOL sequence to use.
     * @return The contents of the card in string format.
     */
    public String getAsString(String eol) {
        StringBuilder sb = new StringBuilder(HEIGHT * (WIDTH + eol.length() + 1) - 1);
        char[][] myGrid = getGrid();
        for (int y = 0; y < myGrid.length; y++) {
            sb.append(myGrid[y]);
            if (y > 0) {
                sb.append(y);
            }
            sb.append(eol);
        }
        return sb.toString();
    }

    /**
     * Get a character from the symbol row or header at a specific column.
     *
     * @param x The column index. This may be less then zero or larger than the
     *     width of the card, in which case it will automatically "wrap around".
     * @return The character in the symbol row or header at the specified
     *     column.
     */
    public synchronized char charAtHeader(int x) {
        if (grid == null) {
            generateGrid();
        }
        return grid[0][Math.mod(x, WIDTH)];
    }
    
    /**
     * Get a character from the body of the card at specific coordinates. Note
     * that this method does not return characters from the symbol row or
     * header, and row zero refers to the topmost row of the body of the card.
     *
     * @param x The column index. This may be less then zero or larger than the
     *     width of the card, in which case it will automatically "wrap around".
     * @param x The row index. Row zero is the topmost row of the body of the
     *     card. This may be less then zero or larger than the height the card,
     *     in which case it will automatically "wrap around".
     * @return The character at the specified coordinates of the body of the
     *     card.
     */
    public synchronized char charAtBody(int x, int y) {
        if (grid == null) {
            generateGrid();
        }
        return grid[Math.mod(y, BODY_HEIGHT) + 1][Math.mod(x, WIDTH)];
    }

    /**
     * Create a new card with a randomly chosen number. A secure random number
     * generator is used so that the card number is truly random.
     *
     * @param digitArea Whether to include an area containing only digits.
     * @param includeSymbols Whether to include symbols.
     * @return A new card with the specified options and a randomly chosen
     *     number.
     */
    public static PasswordCard createRandomCard(boolean digitArea,
            boolean includeSymbols) {
        return new PasswordCard(cardCreationRandomiser.nextLong(), digitArea,
                includeSymbols);
    }

    private void generateGrid() {
        grid = new char[HEIGHT][WIDTH];
        Random random = new Random(number);
        char[] headerChars = HEADER_CHARS.toCharArray();
        shuffle(headerChars, random);
        if (headerChars.length > WIDTH) {
            char[] tmp = headerChars;
            headerChars = new char[WIDTH];
            System.arraycopy(tmp, 0, headerChars, 0, WIDTH);
        }
        grid[0] = headerChars;

        if (digitArea) {
            int halfHeight = 1 + ((HEIGHT - 1) / 2);
            for (int y = 1; y < halfHeight; y++) {
                for (int x = 0; x < WIDTH; x++) {
                    if (includeSymbols && ((x % 2) == 0)) {
                        grid[y][x] = DIGITS_LETTERS_AND_SYMBOLS.charAt(random
                                .nextInt(DIGITS_LETTERS_AND_SYMBOLS.length()));
                    } else {
                        grid[y][x] = DIGITS_AND_LETTERS.charAt(random
                                .nextInt(DIGITS_AND_LETTERS.length()));
                    }
                }
            }
            for (int y = halfHeight; y < HEIGHT; y++) {
                for (int x = 0; x < WIDTH; x++) {
                    grid[y][x] = DIGITS.charAt(random.nextInt(10));
                }
            }
        } else {
            for (int y = 1; y < HEIGHT; y++) {
                for (int x = 0; x < WIDTH; x++) {
                    if (includeSymbols && ((x % 2) == 0)) {
                        grid[y][x] = DIGITS_LETTERS_AND_SYMBOLS.charAt(random
                                .nextInt(DIGITS_LETTERS_AND_SYMBOLS.length()));
                    } else {
                        grid[y][x] = DIGITS_AND_LETTERS.charAt(random
                                .nextInt(DIGITS_AND_LETTERS.length()));
                    }
                }
            }
        }
    }

    /**
     * Private implementation of Collections.shuffle() algorithm, because the
     * Android core classes implement it differently.
     * 
     * @param list
     *            The list of characters to shuffle.
     * @param rnd
     *            The pseudorandom generator instance to use for the shuffle.
     */
    private void shuffle(char[] list, Random rnd) {
        int size = list.length;
        for (int i = size; i > 1; i--)
            swap(list, i - 1, rnd.nextInt(i));
    }

    private void swap(char[] list, int i, int j) {
        char tmp = list[i];
        list[i] = list[j];
        list[j] = tmp;
    }

    private final long number;
    private final boolean digitArea, includeSymbols;
    private char[][] grid;

    public static final int WIDTH = 29, HEIGHT = 9, BODY_HEIGHT = HEIGHT - 1;

    private static final String HEADER_CHARS = "???????????????????$!??????";
    private static final String DIGITS = "0123456789";
    private static final String DIGITS_AND_LETTERS = "23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
    private static final String DIGITS_LETTERS_AND_SYMBOLS = "23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ@#$%&*<>?+{}[]()/\\";
    private static final Random cardCreationRandomiser = new SecureRandom();
}




Java Source Code List

cl.flu0.passcard.MainActivity.java
org.pepsoft.passwordcard.PasswordCard.java
org.pepsoft.util.Math.java
org.pepsoft.util.Tool.java