Shifting set bits in a UInt64 to the right of their respective bytes - 64-bit

I have a UInt64 value with some bits on and some off e.g.:
01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101
How can I easily shift the set bits to the right, such they are to the right end of their respective bytes e.g:
00001111 00001111 00001111 00001111 00001111 00001111 00001111 00001111
I've seen questions which move the on bits all the way to the right of the 64 bit unsigned integer, but I only want to shift them to the right of the byte in which they lie if possible.
Thanks.

using System;
using System.Linq;
namespace ConsoleApplication5
{
public class Program
{
public static void Main(String[] args)
{
var inputAsBinaryString = "01010101 01010101 01010101 01010101 01010101 01010101 01010101 01010101";
var inputAsUInt64 = GetBinaryStringAsUInt64(inputAsBinaryString);
var actualAsUInt64 = GetRightAlignedBytes(inputAsUInt64);
var actualAsBinaryString = GetAsBinaryString(actualAsUInt64);
var expectedAsBinaryString = "00001111 00001111 00001111 00001111 00001111 00001111 00001111 00001111";
var expectedAsUInt64 = GetBinaryStringAsUInt64(expectedAsBinaryString);
} // <-- Set a breakpoint here and inspect the values.
/* Bit-manipulation methods. */
private static UInt64 GetRightAlignedBytes(UInt64 n)
{
var rightAlignedByteArray =
BitConverter
.GetBytes(n)
.Select(b => GetRightAlignedByte(b))
.ToArray();
return BitConverter.ToUInt64(rightAlignedByteArray, 0);
}
/* Shove all of a byte's bits to the right. */
private static Byte GetRightAlignedByte(Byte b)
{
/* The << operator only works on 32 and 64 bit values.
This requires treating the result as an Int32 until it's returned. */
Int32 result = 0;
var numberOfSetBits = GetNumberOfSetBits(b);
for (Byte n = 1; n <= numberOfSetBits; n++)
{
/* Need to set n bits, but only perform n - 1 left shifts. */
result |= 1;
if (n < numberOfSetBits)
result = result << 1;
}
return (Byte) result;
}
private static Byte GetNumberOfSetBits(Byte b)
{
/* There are many ways to count the number of "set" bits in a byte.
This StackOverflow question
http://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
has a mind-numbing collection of answers.
Most of them are probably more efficient than this method. */
Int32 result = 0;
/* The >> operator only works on 32 and 64 bit values.
This requires converting the Byte parameter "b" to an Int32. */
Int32 n = b;
while (n > 0)
{
result += (n & 1);
n = n >> 1;
}
return (Byte) result;
}
/* GetBinaryStringAs* methods */
private static Int32 GetBinaryStringAsInt32(String s)
{
return Convert.ToInt32(String.Join("", s.Trim().Where(c => (c == '0') || (c == '1'))), 2);
}
private static UInt64 GetBinaryStringAsUInt64(String s)
{
return Convert.ToUInt64(String.Join("", s.Trim().Where(c => (c == '0') || (c == '1'))), 2);
}
/* GetAsBinaryString methods. */
private static String GetAsBinaryString_Helper(Byte[] bytes)
{
/* The order of the bytes returned by System.BitConverter.GetBytes()
depends on the CPU architecture. The returned byte array
will round-trip with other BitConverter methods, like its
ToInt32() method. But those same bytes will not round-trip
with any of the System.Convert methods, like ToInt32(String, Int32).
The System.Convert.To* methods expect the order of the bytes they
receive to be the *reverse* of the order returned by
System.BitConverter.GetBytes().
The value returned by this method can - after stripping off the spaces -
be fed into a System.Convert.To*() method.
For example, this round-trip test should print "True":
// Hi byte Lo byte
Int32 n = 257; // 00000000 00000000 00000001 00000001
Console.WriteLine(GetBinaryStringAsInt32(GetAsBinaryString(n)) == n);
*/
return String.Join(" ", bytes.Reverse().Select(b => GetAsBinaryString(b)));
}
private static String GetAsBinaryString(Int32 n)
{
/* Note that signed integers use two's complement
binary representation for negative numbers.
For example, calling this method with a parameter
of -42 returns this string:
11111111 11111111 11111111 11010110
*/
return GetAsBinaryString_Helper(BitConverter.GetBytes(n));
}
private static String GetAsBinaryString(UInt64 n)
{
return GetAsBinaryString_Helper(BitConverter.GetBytes(n));
}
private static String GetAsBinaryString(Byte n)
{
return Convert.ToString(n, 2).PadLeft(8, '0');
}
}
}

Related

How to incorporate mod in rolling hash of Rabin Karp algorithm?

I am trying to implement the Rabin Karp algorithm with mod. The hash function which i am using is:
H1= c1*a^k-1 + c2*a^k-2 +c3*a^k-3 +…+ck*a^0
Here cx is the ASCII value of the character. And to roll it I first drop the first term by subtracting it, then multiply by a and add the new term by multiplying it with a^0.
Now the problem is to deal with large values i have used mod operations but doing that i am not able to roll it correctly. My code is as follows:
public class RabinKarp {
private static final int base = 26;
private static final int mod = 1180637;
public static void main(String[] args) {
String text = "ATCAAGTTACCAATA";
String pattern = "ATA";
char[] textArr = text.toCharArray();
char[] patternArr = pattern.toCharArray();
System.out.println(getMatchingIndex(textArr, patternArr));
}
public static int getMatchingIndex(char[] textArr, char[] patternArr) {
int n = textArr.length;
int m = patternArr.length;
int patternHash = getHashForPatternSize(patternArr, m);
int textHash = getHashForPatternSize(textArr, m);
for(int i = 0; i < n-m; i++) {
if(patternHash == textHash && checkMatch(textArr, patternArr, i, m))
return i;
textHash = rollingHash(textArr, textHash, i, m);
}
return -1;
}
public static boolean checkMatch(char[] textArr, char[] patternArr, int i, int m) {
for(int j = 0; j < m; j++,i++) {
if(textArr[i] != patternArr[j])
return false;
}
return true;
}
public static int rollingHash(char[] textArr, int textHash, int i, int m) {
return (textHash * base - modularExponentiation(base, m, mod) * (int)textArr[i] + (int) textArr[i+m])%mod;
}
public static int getHashForPatternSize(char[] arr, int m) {
int hash = 0;
for(int i = 0, p = m; i < m; i++, p--) {
hash = (hash%mod + calcHash(arr[i], p)%mod)%mod;
}
return hash;
}
public static int calcHash(char alphabet, int p) {
return (((int) alphabet)%mod * modularExponentiation(base, p, mod)%mod)%mod;
}
public static int modularExponentiation(int base, int p, int mod) {
if(p == 0)
return 1;
if(p%2 == 0)
return modularExponentiation((base*base)%mod, p/2, mod);
else
return (base*modularExponentiation((base*base)%mod, (p-1)/2, mod))%mod;
}
}
Problem is that textHash and patternHash do not match at any point. I am sure that the problem is with the mod operations. Can anyone tell how to have mod as well as to use the rolling hash correctly. I would be very thankful.
The usual way to compute a Rabin-Karp rolling hash is to consider the characters in big-endian order, rather than your little-endian solution. This makes the arithmetic much easier since it avoids division. Modular division is non-trivial and you cannot simply implement it as (p/q)%b.
If we take the rolling hash as
H0…k-1 = (c0*ak-1 + c1*ak-2 + c2*ak-3 …+… ck-1*a0) mod b
Then the next term is:
H1…k = ( c1*ak-1 + c2*ak-2 …+… ck-1*a1 + ck*a0) mod b
And we can easily see that
H1…k = (a * H0…k-1 - c0*ak + ck) mod b
If we then precompute m == ak mod b, that becomes:
H1…k = (a * H0…k-1 - m * c0 + ck) mod b
which is much less work on each iteration, and does not depend on division at all.

Javacard applet to subtract two hexadecimal array of byte

I'm try to write a javacard applet that need to add/sub two array of bytes.
the addition was success but the subtraction fail in some cases ("when there is a borrow from the procceding byte").
Can you check my code and improve it to work better?
package phase1;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
import javacard.security.CryptoException;
public class keygen extends Applet {
public static final short _0 = 0;
public final static byte[] one = {(byte) 0xff, (byte) 0xff, (byte) 0xff,(byte) 0xff,(byte) 0xff,(byte) 0xff};
byte [] G = {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x11};
private keygen() {
}
public static void install(byte bArray[], short bOffset, byte bLength)throws ISOException {
try{
new keygen().register();
} catch (Exception e) {
ISOException.throwIt((short) 0x8888);
}
}
public void process(APDU apdu) throws ISOException {
// TODO Auto-generated method stub
if (selectingApplet()) return;
//short sendlen = 0;
byte[] buf = apdu.getBuffer();
byte ins = buf[ISO7816.OFFSET_INS];
byte [] val = new byte [(short) G.length];
short i;
short len = (short) G.length ;
short Alen = (short) (len - 1);
short b = (short) 0 ;
byte[] Z = new byte [(short) len];
byte[] y = new byte [(short) 2];
try{
switch (ins){
case (byte) 0x01: //0x0F
{
Z = addarray (G , one);
apdu.setOutgoing();
buf = Z;
apdu.setOutgoingLength(len);
apdu.sendBytesLong(Z, (short) 0,len);
break;
}
case (byte) 0x02: //0x0F
{ //Z = new byte [(short) 7];
Z = subarray1 (G , one);
apdu.setOutgoing();
buf= Z;
apdu.setOutgoingLength(len);
apdu.sendBytesLong(Z, (short) 0,len);
break;
}
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}catch (CryptoException e) {
ISOException.throwIt(((CryptoException) e).getReason());
}
}
private byte [] addarray (byte [] Arr1, byte [] Arr2 )
{
short i;
short [] X = new short [(short) 6];
short len = (short) Arr1.length ;
short Alen = (short) (len - 1);
byte [] AddArr = new byte [len];
short R = (short) 0;
byte[] Z = new byte [(short) 2];
for (i = Alen; i >= 0 ; i--)
{
X[i] = (short) ((Arr1[i] & 0xFF) + (Arr2[i]&0xff) + R);
Util.setShort(Z, (short) 0, (short) X[i]);
AddArr[i] = (byte) Z[1];
R = (short) (Z[0]);
}
return AddArr;
}
private byte [] subarray1 (byte [] Arr1, byte [] Arr2)
{
short i;
byte [] X = new byte [(short) 6];
short len = (short) Arr1.length ;
short Alen = (short) (len - 1);
byte [] SubArr = new byte [len];
short R = (short) 0;
byte[] Z = new byte [(short) 2];
for (i = Alen; i > 0 ; i--)
{
X[i] = (byte) (Arr1[i] - Arr2[i] - (byte) R );
Util.setShort(Z, (short) 0, (short) X[i]);
SubArr[i] = (byte) Z[1];
R = (short) (Z[0] );
}
return SubArr;
}
}
There is an optional class in Java Card API named bigIntNumber. If your card doesn't implemented it, I share its source code with you:
/**
* Class BigIntNumber provides addition, subtraction and comparison functions
* for unsigned integers represented in byte array format in bug endian order.
*
*/
public class BigIntNumber {
/**
* Add two unsigned integers represented in array A and B. The sum stored in
* array C
*
* #param A the left operand
* #param AOff the starting position in array A.
* #param B the right operand.
* #param BOff the starting position in array B.
* #param C the result of (A+B)
* #param COff the starting position in array C.
* #param len the number of bytes in the operands as well in the computed
* result. this parameter can not be a negative number.
* #return false if the result overflows. if overflows occurs, the sum would
* be the true mathematical result with the most significant bytes discarded
* to fit into array C of the specified length.
* #throws ArrayOuutOfBoundException if array access out of bound.
*/
public static boolean add(byte[] A, byte AOff, byte[] B, byte BOff, byte[] C, byte COff, byte len) {
short result = 0;
for (len = (byte) (len - 1); len >= 0; len--) {
// add two unsigned bytes and the carry from the
// previous byte computation.
result = (short) (getUnsignedByte(A, AOff, len) + getUnsignedByte(B, BOff, len) + result);
// store the result in byte array C
C[(byte) (len + COff)] = (byte) result;
// has a carry?
if (result > 0x00FF) {
result = 1;
result = (short) (result + 0x100);
} else {
result = 0;
}
}
//produce overflow in the sum.
if (result == 1) {
return false;
}
return true;
}
/**
* Subtract two unsigned integers represented in array A and B. The sum stored in
* array C
*
* #param A the left operand
* #param AOff the starting position in array A.
* #param B the right operand.
* #param BOff the starting position in array B.
* #param C the result of (A-B)
* #param COff the starting position in array C.
* #param len the number of bytes in the operands as well in the computed
* result. this parameter can not be a negative number.
* #return false if the result underflows. if underflows occurs, the sum would
* be the mathematical result of A + ~B + 1.
* #throws ArrayOuutOfBoundException if array access out of bound.
*/
public static boolean subtract(byte[] A, byte AOff, byte[] B, byte BOff, byte[] C, byte COff, byte len) {
byte borrow = 0;
short result;
for (len = (byte) (len - 1); len >= 0; len--) {
// subtract one unsigned byte from the other.
// also subtract the borrow from the previous byte computation.
result = (short) (getUnsignedByte(A, AOff, len) - getUnsignedByte(B, BOff, len) - borrow);
// need to borrow?
if (result < 0) {
borrow = 1;
result = (short) (result + 0x100);
} else {
borrow = 0;
}
// store the result in C
C[(byte) (len + COff)] = (byte) result;
}
// is the result underflow?
if (borrow == 1) {
return false;
}
return true;
}
/**
* Compare two unsigned integers represented in array A and B. The sum stored in
* array C
*
* #param A the left operand
* #param AOff the starting position in array A.
* #param B the right operand.
* #param BOff the starting position in array B.
* #param C the result of (A-B)
* #param COff the starting position in array C.
* #param len the number of bytes in the operands as well in the computed
* result. this parameter can not be a negative number.
* #return the result of comparison as below:
* 0 if identical
* 1 if the left operand is bigger than the right operand
* -1 if the left operand is smaller than the right operand
* #throws ArrayOuutOfBoundException if array access out of bound.
*/
public static byte compare(byte[] A, byte AOff, byte[] B, byte BOff, byte len) {
byte count = (byte) 0;
for (; count < len; count++) {
short C = getUnsignedByte(A, AOff, count);
short D = getUnsignedByte(A, AOff, count);
if (C < D) {
return -1;
}
if (C > D) {
return 1;
}
}
return 0;
}
/**
*
* Get the unsigned byte at the index (AOff + count)
*/
private static short getUnsignedByte(byte[] A, byte AOff, byte count) {
return (short) (A[(short) (count + AOff)] & 0x00FF);
}
}
And this is a sample applet that I wroto to show you how does the above class methods work:
package phase1;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
import static phase1.BigIntNumber.*;
public class TestBigInt extends Applet {
// Defining global arrays for Operands A and B.
// LenA and LenB are defined to check if equal length of A and B are going
// to add, compare or subtract or not. Len of operands musb be equal between 1 byte to 8 bytes.
public static byte[] OpA = new byte[8];
public static byte[] OpB = new byte[8];
public static byte[] result = new byte[8];
public static byte lenA;
public static byte lenB;
// Defining supported INS valuse for APDU Command.
public static final byte INS_INIT_OPERAND = (byte) 0x10;
public static final byte INS_ADD = (byte) 0x20;
public static final byte INS_SUBTRACT = (byte) 0x30;
public static final byte INS_COMPARE = (byte) 0x40;
// P1 parameter in the APDU command
public static final byte OPERAND_A = 0x01;
public static final byte OPERAND_B = 0x02;
// Defining Exception Status Words
public static short SW_NOT_EQUAL_LENGTH = (short) 0x6910;
public static short SW_OVERFLOW_OCCURS = (short) 0x6911;
public static short SW_UNDERFLOW_OCCURS = (short) 0x6912;
private TestBigInt() {
}
public static void install(byte bArray[], short bOffset, byte bLength) throws ISOException {
new TestBigInt().register();
}
public void process(APDU apdu) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS]) {
case INS_INIT_OPERAND:
apdu.setIncomingAndReceive();
if (buf[ISO7816.OFFSET_LC] > (byte) 0x08) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
if (buf[ISO7816.OFFSET_P1] == OPERAND_A) {
Util.arrayCopyNonAtomic(buf, ISO7816.OFFSET_CDATA, OpA, (short) 0x00, buf[ISO7816.OFFSET_LC]);
lenA = buf[ISO7816.OFFSET_LC];
} else if (buf[ISO7816.OFFSET_P1] == OPERAND_B) {
Util.arrayCopyNonAtomic(buf, ISO7816.OFFSET_CDATA, OpB, (short) 0x00, buf[ISO7816.OFFSET_LC]);
lenB = buf[ISO7816.OFFSET_LC];
} else {
ISOException.throwIt(ISO7816.SW_WRONG_P1P2);
}
break;
case INS_ADD:
if (lenA != lenB) {
ISOException.throwIt(SW_NOT_EQUAL_LENGTH);
}
if (add(OpA, (byte) 0x00, OpB, (byte) 0x00, result, (byte) 0x00, lenA)) {
apdu.sendBytesLong(result, (short) 0x00, (short) lenA);
} else {
ISOException.throwIt(SW_OVERFLOW_OCCURS);
}
break;
case INS_SUBTRACT:
if (lenA != lenB) {
ISOException.throwIt(SW_NOT_EQUAL_LENGTH);
}
if (subtract(OpA, (byte) 0x00, OpB, (byte) 0x00, result, (byte) 0x00, lenA)) {
apdu.sendBytesLong(result, (short) 0x00, (short) lenA);
} else {
ISOException.throwIt(SW_UNDERFLOW_OCCURS);
}
break;
case INS_COMPARE:
// ...
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}
It seems works fine:
Connect successful.
Download Cap begin...
Download Cap successful.
Install Applet begin...
Install Applet successful.
Select Applet begin...
Select Applet successful.
Send: 00 10 01 00 07 11 22 33 44 55 66 77 00 //Initilizing Operand A
Recv: 90 00
Time used: 21.000 ms
Send: 00 10 02 00 07 11 22 33 44 55 66 77 00 //Initlizing Operand B
Recv: 90 00
Time used: 19.000 ms
Send: 00 20 00 00 00 // Compute A+B
Recv: 22 44 66 88 AA CC EE 90 00
Time used: 67.000 ms
Send: 00 30 00 00 00 // Compute A-B
Recv: 00 00 00 00 00 00 00 90 00
Time used: 73.000 ms
Send: 00 10 02 00 07 00 00 44 44 44 44 44 00 // Changing Operand B
Recv: 90 00
Time used: 14.000 ms
Send: 00 20 00 00 00 // Compute A+B again
Recv: 11 22 77 88 99 AA BB 90 00
Time used: 66.000 ms
Send: 00 30 00 00 00 // Compute A-B
Recv: 11 21 EF 00 11 22 33 90 00
Time used: 71.000 ms
Sorry, I didn't checked your code. Just two simple hint:
1- Try to don't use dynamic fields in methods. Java Card doesn't support automatic garbage collection, so the memory that you assign to a field dynamically (i.e. using new keyword), will not reclaimed automatically until calling requestObjectDeletion() method (and it's optional too!) :)
2- 0x8888 is not a standard status world in the ISO7816-4 standard and some smart cards has problem with non-standard status words. Try to choose 6XXX (60XX is also non-standard value) or 9XXX for status words.

how to reverse AudioTrack play()

I have buffer (array) full of audio data, filled with AudioRecord method.
I want play this reversed. When I try to reverse the buffer I just get noise.
public void startWriteAndPlayProcess (){
writeAudio();
playAudio();
}
private void writeAudio(){
audioTrack.write(reverseArray(audioBuffer), 0, bufferSize);
}
private void playAudio(){
audioTrack.play();
}
private byte [] reverseArray ( byte array []){
byte [] array1 = new byte [array.length];
for (int i=0; i<array1.length; i++){
array1[i]= array[array1.length-1-i];
}
return array1;
}
What You people can recomend?
The underlying audio samples are actually an array of shorts (16-bit) or ints (24 or 32-bit). If you just reverse the raw byte array then you are putting the least significant byte on the top and this will make your signal sound like noise. To get it to work properly you need to first convert the byte array to an array of the proper type, reverse that, and then convert it back into a byte array.
private void writeAudio()
{
short[] shortArray = toShortArray(audioBuffer);
short[] reversedShortArray = reverseArray(shortArray);
byte[] reversedByteArray = toByteArray(reversedShortArray);
audioTrack.write(reversedByteArray, 0, bufferSize);
}
private short[] toShortArray(byte[] byteArray)
{
short[] shortArray = new short[byteArray.length / 2];
for (int i = 0 ; i < shortArray.length; i)
{
shortArray[i] = (short)((short)byteArray[i*2] | (short)(byteArray[i*2 + 1] << 8));
// alternatively - depending on the endianess of the data:
// shortArray[i] = (short)((short)byteArray[i*2] << 8 | (short)(byteArray[i*2 + 1]));
}
return shortArray;
}
Of course you'll have to change the type of reverseArray. I'll leave it up to you to figure out how to go back to bytes from the short array or to write the int versions of them if that's what you need.

how to find decode way to decode a USSD Command's result in c#?

I'm working on my GSM modem (Huawei E171) to send USSD commands.
to do this i use this commands at the first:
AT+CMGF=1
AT+CSCS=? ----> result is "IRA" this is my modem default
after that i sent these commands and i have got these results and everything works fine.
//*141*1# ----->to check my balance
+CUSD:
0,"457A591C96EB40B41A8D0692A6C36C17688A2E9FCB667AD87D4EEB4130103D
0C8281E4753D0B1926E7CB2018881E06C140F2BADE5583819A4250D24D2FC
BDD653A485AD787DD65504C068381A8EF76D80D2287E53A55AD5653D554
31956D04",15
//*100# ----> this command give me some options to charge my mobile
+CUSD:
1,"06280627062C06470020062706CC06310627064606330644000A0030002E062E0
63106CC062F00200634062706310698000A0031002E067E062706330627063106A
F0627062F000A0032002E0622067E000A0033002E06450644062A000A003
4002E06330627064506270646000A0035002E067E0627063106330
6CC06270646000A002300200028006E0065007800740029000A",72
i found some codes to decode these result:
to decode checking balance result i used:
string result141="457A591C96EB40B41A8D0692A6C36C17688A......."
byte[] packedBytes = ConvertHexToBytes(result141);
byte[] unpackedBytes = UnpackBytes(packedBytes);
//gahi in kar mikone gahi balkaee nafahmidam chera
string o = Encoding.Default.GetString(unpackedBytes);
my function's codes are:
public static byte[] ConvertHexToBytes(string hexString)
{
if (hexString.Length % 2 != 0)
return null;
int len = hexString.Length / 2;
byte[] array = new byte[len];
for (int i = 0; i < array.Length; i++)
{
string tmp = hexString.Substring(i * 2, 2);
array[i] =
byte.Parse(tmp, System.Globalization.NumberStyles.HexNumber);
}
return array;
}
public static byte[] UnpackBytes(byte[] packedBytes)
{
byte[] shiftedBytes = new byte[(packedBytes.Length * 8) / 7];
int shiftOffset = 0;
int shiftIndex = 0;
// Shift the packed bytes to the left according
//to the offset (position of the byte)
foreach (byte b in packedBytes)
{
if (shiftOffset == 7)
{
shiftedBytes[shiftIndex] = 0;
shiftOffset = 0;
shiftIndex++;
}
shiftedBytes[shiftIndex] = (byte)((b << shiftOffset) & 127);
shiftOffset++;
shiftIndex++;
}
int moveOffset = 0;
int moveIndex = 0;
int unpackIndex = 1;
byte[] unpackedBytes = new byte[shiftedBytes.Length];
//
if (shiftedBytes.Length > 0)
{
unpackedBytes[unpackIndex - 1] =
shiftedBytes[unpackIndex - 1];
}
// Move the bits to the appropriate byte (unpack the bits)
foreach (byte b in packedBytes)
{
if (unpackIndex != shiftedBytes.Length)
{
if (moveOffset == 7)
{
moveOffset = 0;
unpackIndex++;
unpackedBytes[unpackIndex - 1] =
shiftedBytes[unpackIndex - 1];
}
if (unpackIndex != shiftedBytes.Length)
{
// Extract the bits to be moved
int extractedBitsByte = (packedBytes[moveIndex] &
_decodeMask[moveOffset]);
// Shift the extracted bits to the proper offset
extractedBitsByte =
(extractedBitsByte >> (7 - moveOffset));
// Move the bits to the appropriate byte
//(unpack the bits)
int movedBitsByte =
(extractedBitsByte | shiftedBytes[unpackIndex]);
unpackedBytes[unpackIndex] = (byte)movedBitsByte;
moveOffset++;
unpackIndex++;
moveIndex++;
}
}
}
// Remove the padding if exists
if (unpackedBytes[unpackedBytes.Length - 1] == 0)
{
byte[] finalResultBytes = new byte[unpackedBytes.Length - 1];
Array.Copy(unpackedBytes, 0,
finalResultBytes, 0, finalResultBytes.Length);
return finalResultBytes;
}
return unpackedBytes;
}
but to decode second result i used:
string strHex= "06280627062C06470020062706CC06310......";
strHex = strHex.Replace(" ", "");
int nNumberChars = strHex.Length / 2;
byte[] aBytes = new byte[nNumberChars];
using (var sr = new StringReader(strHex))
{
for (int i = 0; i < nNumberChars; i++)
aBytes[i] = Convert.ToByte(
new String(new char[2] {
(char)sr.Read(), (char)sr.Read() }), 16);
}
string decodedmessage= Encoding.BigEndianUnicode.
GetString(aBytes, 0, aBytes.Length);
both of theme works current but why i should different decoding way to decode these results?
from where i can find, i should use which one of these two types of decoding?
USSD command responses +CUSD unsolicited responses are formatted as follows:
+CUSD: <m>[<str_urc>[<dcs>]]
Where "m" is the type of action required, "str_urc" is the response string, and "dcs" is the response string encoding.
This quote is from a Siemens Cinterion MC55i manual but applies generally to other modem manufacturers:
If dcs indicates that GSM 03.38 default alphabet is used TA converts GSM alphabet into current TE character
set according to rules of GSM 07.05 Annex A. Otherwise in case of invalid or omitted dcs conversion of
str_urc is not possible.
USSD's can be sent in 7-Bit encoded format or UC2 hence when looking at your two example responses you can see either a DCS of 15 or 72.
GSM 03.38 Cell Broadcast Data Coding Scheme in integer format (default 15). In case of an invalid or omitted
dcs from the network side (MT) will not be given out.
So if you get a DCS of 15 then it is 7-Bit encoded. And if it's 72 then it will be UC2. So from this you can easily select either your first decoding routine or second.

What does following code means int val = str.charAt(i) - 'a';?

The code is taken from career cup book
public static boolean isUniqueChars(String str) {
if (str.length() > 256) {
return false;`
}
int checker = 0;
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i) - 'a';
if ((checker & (1 << val)) > 0) return false;
checker |= (1 << val);
}
return true;
}
Thank you for explanation and I am not sure what do I get. Lets look at the following code-
public class ConvertAscii {
public static void main(String args[]){
String str ="Hello How are you";
int i =0;
for(i=0;i<str.length();i++){
System.out.println(str.charAt(i)-'a');
}
}
}
It gives me following output-
-24
12
32
34
etc
Also as in the above example we have
For example if str is "fbhsdsbfid" and i is 4 then val is equal to 3. What does subtracting ascii value of character 'a' from another character results in? Please explain more
It takes the character which is at index i in str and substracts the ASCII value of the character 'a'.
For example if str is "fbhsdsbfid" and i is 4 then val is equal to 3.
To answer your question for index i = 4, the character at index 4 is 'd' and it's corresponding ASCII value is 64.
The ASCII value of 'a' is 61.Therefore, str.charAt(i) - 'a' gives 64 - 61 = 3.

Resources