生成随机条码 - 一个设计问题 [英] Generate random bar codes - a design issue

查看:140
本文介绍了生成随机条码 - 一个设计问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我修复了生成条形码的java代码中的错误(线程问题)。根据设计,条形码只是一个数字,下一个未使用条形码是序列中的下一个。有990亿可能的数字。

I'm fixing bugs (thread issues) in java code that generate bar codes. As per design the barcode is just a number and the next "not used" bar code is next in the sequence. There are 99 billion possible numbers.

首先,我不喜欢自动递增的数字,因为安全问题。我想生成随机数字。

First of all I don't like auto incremented numbers because of security issues. I want to generate random numbers.

已经使用的条形码存储在数据库表中。

Already used bar codes are stored in a database table.

相当容易创建一个随机数,并在条形码正在使用时检查表格。但逻辑将不得不循环,直到它发现一个随机数不使用。

It is quite easy to create a random number and check against the table if the barcode is in use. But the logic will have to loop until it finds a random number is not in use. By time this could be a heavy task.

我认为线程安全缓存有1000个自由条形码可以完成这项工作,但是构建或更新缓存可以是相当

I think that a thread safe cache with 1000 free bar codes would do the job, but building or renewing the cache can be quite heavy.

对可执行查找的查询的设计的任何建议或可返回一系列自由随机数的查询?

Any suggestions to a design of a query that does the lookup or a query that can return a range of free random numbers?

我正在使用hibernate标准。

I'm using hibernate criterias.

感谢

推荐答案

您可以使用线性反馈移位寄存器 。他们可以在一个循环中以一个特定的位数遍历所有数字,而不重复,但是看起来是一个随机的顺序。

You could use a Linear Feedback Shift Register. They can step through all numbers with a specific number of bits in a cycle without repeating but in a seemingly random order.

这应该工作 - 这是一个严重削减版本的一个我写了一段时间。您必须按照链接中所述选择原始多项式。

This should work - it is a severely cut-down version of one I wrote a while ago. You will have to choose your primitive polynomial as described in the links.

您可以找到随机选择的原始多项式列表此处

You can find a list of randomly chosen primitive polynomials here.

/**
 * Linear feedback shift register
 *
 * Taps can be found at: 
 * See http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf 
 * See http://mathoverflow.net/questions/46961/how-are-taps-proven-to-work-for-lfsrs/46983#46983
 * See http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm 
 * See http://www.yikes.com/~ptolemy/lfsr_web/index.htm 
 * See http://seanerikoconnor.freeservers.com/Mathematics/AbstractAlgebra/PrimitivePolynomials/overview.html 
 *
 * @author OldCurmudgeon
 */
public class LFSR implements Iterable<BigInteger> {

    // Bit pattern for taps.
    private final BigInteger taps;
    // Where to start (and end).
    private final BigInteger start;

    // The poly must be primitive to span the full sequence.
    public LFSR(BigInteger primitivePoly, BigInteger start) {
        // Where to start from (and stop).
        this.start = start.equals(BigInteger.ZERO) ? BigInteger.ONE : start;
        // Knock off the 2^0 coefficient of the polynomial for the TAP.
        this.taps = primitivePoly.shiftRight(1);
    }

    @Override
    public Iterator<BigInteger> iterator() {
        return new LFSRIterator(start);
    }

    private class LFSRIterator implements Iterator<BigInteger> {
        // The last one we returned.

        private BigInteger last = null;
        // The next one to return.
        private BigInteger next = null;

        public LFSRIterator(BigInteger start) {
            // Do not return the seed.
            last = start;
        }

        @Override
        public boolean hasNext() {
            if (next == null) {
                /*
                 * Uses the Galois form.
                 *
                 * Shift last right one.
                 *
                 * If the bit shifted out was a 1 - xor with the tap mask.
                 */
                boolean shiftedOutA1 = last.testBit(0);
                // Shift right.
                next = last.shiftRight(1);
                if (shiftedOutA1) {
                    // Tap!
                    next = next.xor(taps);
                }
                // Never give them `start` again.
                if (next.equals(start)) {
                    // Could set a finished flag here too.
                    next = null;
                }
            }
            return next != null;
        }

        @Override
        public BigInteger next() {
            // Remember this one.
            last = hasNext() ? next : null;
            // Don't deliver it again.
            next = null;
            return last;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported.");
        }

        @Override
        public String toString() {
            return LFSR.this.toString()
                    + "[" + (last != null ? last.toString(16) : "")
                    + "-" + (next != null ? next.toString(16) : "") + "]";
        }
    }

    @Override
    public String toString() {
        return "(" + taps.toString(32) + ")-" + start.toString(32);
    }

}

public void test(int[] tap, int base) {
    System.out.println("Test: " + Arrays.toString(tap));
    // Build the BigInteger.
    BigInteger primitive = BigInteger.ZERO;
    for (int bit : tap) {
        primitive = primitive.or(BigInteger.ONE.shiftLeft(bit));
    }
    // Stop at 100.
    int count = 100;
    LFSR lfsr = new LFSR(primitive, BigInteger.ONE);
    for (BigInteger b : lfsr) {
        if (count-- > 0) {
            System.out.println(b.toString(base));
        } else {
            break;
        }

    }
}

public void test() {
    // Just 6 bits.
    int[] tap7 = {6, 5, 0};
    test(tap7, 10);
    // An example 48-bit tap.
    int[] tap48 = {48, 46, 45, 44, 42, 40, 36, 34, 33, 32, 29, 27, 26, 20, 17, 16, 12, 11, 10, 5, 3, 1, 0};
    test(tap48, 16);
}

这篇关于生成随机条码 - 一个设计问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆