OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Blame | Last modification | View Log | RSS feed

/*
 * Copyright 2014 Robin Stuart
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package uk.org.okapibarcode.backend;

/**
 *
 * @author <a href="mailto:rstuart114@gmail.com">Robin Stuart</a>
 */
public class ReedSolomon {
    private int logmod;
    private int rlen;

    private int[] logt;
    private int[] alog;
    private int[] rspoly;
    public int[] res;

    public int getResult(final int count) {
        return this.res[count];
    }

    public void init_gf(final int poly) {
        int m, b, p, v;

        // Find the top bit, and hence the symbol size
        for (b = 1, m = 0; b <= poly; b <<= 1) {
            m++;
        }
        b >>= 1;
        m--;

        // Calculate the log/alog tables
        this.logmod = (1 << m) - 1;
        this.logt = new int[this.logmod + 1];
        this.alog = new int[this.logmod];

        for (p = 1, v = 0; v < this.logmod; v++) {
            this.alog[v] = p;
            this.logt[p] = v;
            p <<= 1;
            if ((p & b) != 0) {
                p ^= poly;
            }
        }
    }

    public void init_code(final int nsym, int index) {
        int i, k;

        this.rspoly = new int[nsym + 1];

        this.rlen = nsym;

        this.rspoly[0] = 1;
        for (i = 1; i <= nsym; i++) {
            this.rspoly[i] = 1;
            for (k = i - 1; k > 0; k--) {
                if (this.rspoly[k] != 0) {
                    this.rspoly[k] = this.alog[(this.logt[this.rspoly[k]] + index) % this.logmod];
                }
                this.rspoly[k] ^= this.rspoly[k - 1];
            }
            this.rspoly[0] = this.alog[(this.logt[this.rspoly[0]] + index) % this.logmod];
            index++;
        }
    }

    public void encode(final int len, final int[] data) {
        int i, k, m;

        this.res = new int[this.rlen];
        for (i = 0; i < this.rlen; i++) {
            this.res[i] = 0;
        }

        for (i = 0; i < len; i++) {
            m = this.res[this.rlen - 1] ^ data[i];
            for (k = this.rlen - 1; k > 0; k--) {
                if (m != 0 && this.rspoly[k] != 0) {
                    this.res[k] = this.res[k - 1] ^ this.alog[(this.logt[m] + this.logt[this.rspoly[k]]) % this.logmod];
                } else {
                    this.res[k] = this.res[k - 1];
                }
            }
            if (m != 0 && this.rspoly[0] != 0) {
                this.res[0] = this.alog[(this.logt[m] + this.logt[this.rspoly[0]]) % this.logmod];
            } else {
                this.res[0] = 0;
            }
        }
    }
}