Java tutorial
//package com.java2s; import java.math.BigInteger; public class Main { private static final int[] EMPTY_INTS = new int[0]; public static int[] generateCompactWindowNaf(int width, BigInteger k) { if (width == 2) { return generateCompactNaf(k); } if (width < 2 || width > 16) { throw new IllegalArgumentException("'width' must be in the range [2, 16]"); } if ((k.bitLength() >>> 16) != 0) { throw new IllegalArgumentException("'k' must have bitlength < 2^16"); } if (k.signum() == 0) { return EMPTY_INTS; } int[] wnaf = new int[k.bitLength() / width + 1]; // 2^width and a mask and sign bit set accordingly int pow2 = 1 << width; int mask = pow2 - 1; int sign = pow2 >>> 1; boolean carry = false; int length = 0, pos = 0; while (pos <= k.bitLength()) { if (k.testBit(pos) == carry) { ++pos; continue; } k = k.shiftRight(pos); int digit = k.intValue() & mask; if (carry) { ++digit; } carry = (digit & sign) != 0; if (carry) { digit -= pow2; } int zeroes = length > 0 ? pos - 1 : pos; wnaf[length++] = (digit << 16) | zeroes; pos = width; } // Reduce the WNAF array to its actual length if (wnaf.length > length) { wnaf = trim(wnaf, length); } return wnaf; } public static int[] generateCompactNaf(BigInteger k) { if ((k.bitLength() >>> 16) != 0) { throw new IllegalArgumentException("'k' must have bitlength < 2^16"); } if (k.signum() == 0) { return EMPTY_INTS; } BigInteger _3k = k.shiftLeft(1).add(k); int bits = _3k.bitLength(); int[] naf = new int[bits >> 1]; BigInteger diff = _3k.xor(k); int highBit = bits - 1, length = 0, zeroes = 0; for (int i = 1; i < highBit; ++i) { if (!diff.testBit(i)) { ++zeroes; continue; } int digit = k.testBit(i) ? -1 : 1; naf[length++] = (digit << 16) | zeroes; zeroes = 1; ++i; } naf[length++] = (1 << 16) | zeroes; if (naf.length > length) { naf = trim(naf, length); } return naf; } private static byte[] trim(byte[] a, int length) { byte[] result = new byte[length]; System.arraycopy(a, 0, result, 0, result.length); return result; } private static int[] trim(int[] a, int length) { int[] result = new int[length]; System.arraycopy(a, 0, result, 0, result.length); return result; } }