All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.ejb.base.sfsb.util.ScrambledKeyGenerator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejb.base.sfsb.util;


import org.glassfish.security.common.SharedSecureRandomImpl;

import com.sun.enterprise.util.Utility;

/**
 * A utility class that generates stateful session keys using two longs
 * The session id generated by this class is guarenteed to be unique as
 * long as the system clock is never reset to a previous value
 *
 * The hashCode of the SessionKey generated by ScrambledKeyGenerator
 * also allows uniform distribution of keys when hashed in a HashMap
 *
 * @author  Mahesh Kannan
 */
public class ScrambledKeyGenerator extends SimpleKeyGenerator {

    private int cachedTime = (int) System.currentTimeMillis();

    public ScrambledKeyGenerator() {
        init((int) System.currentTimeMillis(), System.identityHashCode(this));
    }


    public ScrambledKeyGenerator(byte[] ipAddress, int port) {
        init(Utility.bytesToInt(ipAddress, 0), port);
    }


    public ScrambledKeyGenerator(long val) {
        init((int) (val >>> 32), (int) ((val << 32) >>> 32));
    }


    private void init(int hi, int lo) {
        byte[] hiBytes = new byte[4];
        Utility.intToBytes(hi, hiBytes, 0);
        byte[] loBytes = new byte[4];
        Utility.intToBytes(lo, loBytes, 0);

        swapBytes(hiBytes, loBytes, 2, 3);
        swapBytes(loBytes, loBytes, 2, 3);
        swapBytes(hiBytes, loBytes, 3, 0);
        swapBytes(hiBytes, hiBytes, 0, 3);
        swapBytes(hiBytes, loBytes, 1, 3);

        swapBytes(hiBytes, hiBytes, 0, 1);
        swapBytes(loBytes, loBytes, 2, 3);

        this.prefix = Utility.bytesToInt(hiBytes, 0);
        this.prefix <<= 32;

        this.suffix = Utility.bytesToInt(loBytes, 0);
        this.suffix <<= 32;

        // Inital isCounter value
        this.idCounter = 0;

        // Set the default time value
        this.cachedTime = (int) System.currentTimeMillis();
    }


    private static final void swapBytes(byte[] a, byte[] b, int index1, int index2) {
        byte temp = a[index1];
        a[index1] = b[index2];
        b[index2] = temp;
    }


    /**
     * Create and return the sessionKey.
     *
     * @return the sessionKey object
     */
    @Override
    public SimpleSessionKey createSessionKey() {
        int id = 0;
        synchronized (this) {
            id = ++idCounter;
            if (id < 0) {
                // idCounter wrapped around!!
                id = idCounter = 1;
            }

            if ((id & 0x000000FF) == 0) {
                cachedTime = (int) System.currentTimeMillis();
            }
        }

        return new SimpleSessionKey(prefix + cachedTime,
            // suffix + System.identityHashCode(new Object()), id
            suffix + SharedSecureRandomImpl.get().nextInt(), id);
    }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy