SIMPLE-TLV vs BER-TLV - nfc

I have found in docs they are referring to SIMPLE-TLV and BER-TLV . I was look into most of the EMV and GP docs but they have not mentioned the different.
Could anyone help me to understand the difference of two ?

Data fields in ISO/IEC 7816-4 for smart cards
BER encoding
This is the specification of the more common BER encoding used by ISO/IEC 7816-4:
Each BER-TLV data object shall consists of 2 or 3 consecutive fields
(see ISO/IEC 8825 and annex D).
The tag field T consists of one or more consecutive bytes. It encodes
a class, a type and a number. The length field consists of one or more
consecutive bytes. It encodes an integer L. If L is not null, then the
value field V consists of L consecutive bytes. If L is null, then the
data object is empty: there is no value field.
Note that ISO/IEC 7816 only allows the use of up to 5 length bytes (specifying a size up to 2^32 - 1 bytes) in the current standard. Indefinite length encoding is not supported either. These limitations are specific to smart cards. Note that 4 and 5 byte length encodings were introduced in a later version of ISO/IEC 7816-4; earlier cards / card reading applications may only support 3 length bytes (i.e. a value size up to 64KiB bytes, instead of 4GiB).
The BER TLV specification is much more expansive (which is why SIMPLE-TLV is called "simple"). I won't go into the details too much as there is plenty of information available on the internet. To name just a few differences, the tags have syntactical meaning and may consist of multiple bytes and the length encoding is rather complex.
Normally BER should only be used as an encoding of ASN.1 structures, with the ASN.1 syntax defining the structure. ISO 7816-4 however messes this up and only specifies the BER tag bytes directly.
Note that sometimes DER is specified instead of BER. In that case you should only use the minimum number of bytes for the size of the length field - e.g. a single length byte with value 05 in the samples below. The ISO/IEC specification of BER encoding is basically a copy of the US specific X.690 standard, also reflected in the international standard ISO/IEC 8825-1 (both payware).
SIMPLE-TLV encoding
The BER specification in ISO/IEC 7816-4 is followed by the SIMPLE-TLV specification. SIMPLE-TLV is specific to ISO 7816-4.
Each SIMPLE-TLV data object shall consist of 2 or 3 consecutive
fields.
The tag field T consists of a single byte encoding only a number from
1 to 254 (e.g. a record identifier). It codes no class and no
construction-type. The length field consists of 1 or 3 consecutive
bytes. If the leading byte of the length field is in the range from
'00' to 'FE', then the length field consists of a single byte encoding
an integer L valued from 0 to 254. If the leading byte is equal to
'FF', then the length field continues on the two subsequent bytes
which encode an integer L with a value from 0 to 65535. If L in not
null, then the value field V consists of consecutive bytes. If L is
null, then the data object is empty: there is no value field.
Note that the standard forgets to specify the endianness directly. You can however assume big endian encoding within ISO/IEC 7816-4.
Samples
The following samples are all used to convey the same tag number (which defines the field) and value, except one that defines tag number 31 for BER.
Sample SIMPLE-TLV
0F 05 48656C6C6F // tag number 15, length 5 then the value
0F FF0005 48656C6C6F // tag number 15, length 5 (two bytes), then the value
Sample BER-TLV:
4F 05 48656C6C6F // *application specific*, primitive encoding of tag number 15, length 5 then the value
4F 8105 48656C6C6F // the same, using two bytes to encode the length
4F 820005 48656C6C6F // the same, using three bytes to encode the length
4F 83000005 48656C6C6F // the same, using four bytes to encode the length
4F 8400000005 48656C6C6F // the same , using five bytes to encode the length
5F0F 05 48656C6C6F // **invalid** encoding of the same, with two bytes for the tag, specifiying a tag number 15 which is smaller than 31
5F1F 05 48656C6C6F // application specific, primitive encoding of **tag number 31**
In the last example with the two byte tag encoding, the first byte is 40 hex, where the first 3 leftmost bits 010 specify application specific encoding, adding the magic value 1F (31) to it to indicate that another byte will follow with the actual tag number, again 1F, so value 31.
Differences
The following differences should be noted:
SIMPLE-TLV is a different method of encoding for tag and length (although the encoding may look similar, e.g. when using a single byte to indicate the length part)
SIMPLE-TLV does not contain information about the class of the field, e.g. if it is defined for ASN.1 (because it is not linked to ASN.1)
SIMPLE-TLV does not contain information if it is primitive or constructed (primitive directly specifies a value, constructed means nested TLV structures)
SIMPLE-TLV has restrictions regarding the tag number (between 1 and 254, inclusive) and length (up to 65535)

Simple TLV simply consists of Tag (or Type), Length, and Value.
The BER-TLV is a special TLV which has one or more TLV inside its Value. So it has composite structure.
Tag1 Len1 Tag2-Len2-Value2 Tag3-Len3-Value3 ... TagN-LenN-ValueN
------------------------Value1------------------------

[Example C# code for Bert-Tlv Parser][1]:
[1]https://github.com/umitkoc/BertTlv
public class Tlv : ITlv, IFile
{
List<TlvModel> modelList=new();
string parser = "";
string length = "";
String empty = "";
string ascii = "";
int decValue = 0;
int step = 0;
public Tlv(String data)
{
TlvParser(data.Replace(" ",""));
}
public void readTag()
{
String line = "";
StreamReader sr = new StreamReader("taglist.txt");
while ((line = sr.ReadLine()) != null)
{
modelList.Add(new()
{
tag = line.Split(",")[0].Trim(),
description = line.Split(",")[1].Trim()
});
}
sr.Close();
}
public void insertTag()
{
try
{
StreamWriter sw = new StreamWriter("test.txt");
foreach (var item in modelList)
{
sw.WriteLine($"{item.tag},{item.description}");
}
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
public int writeFile(String parser)
{
StreamWriter sw = new StreamWriter("output.txt");
sw.WriteLine(parser);
sw.Close();
return 0;
}
private int TlvParser(String data, int i = 0, string tag = "")
{
if (i == 0)
{
readTag();
}
if (i < data.Length)
{
tag += data[i];
TlvModel model = getTag(tag);
if (model != null)
{
decValue = int.Parse(data.Substring(i + 1, 2), System.Globalization.NumberStyles.HexNumber);
// lengthControl(data,i+3,decValue);
if (model.description.Contains("Template"))
{
parser += $"{empty}|------ tag: {model.tag}({model.description})\n";
step += 1;
empty = Empty();
return TlvParser(data, i + 3, "");
}
else
{
parser += $"{empty}|------ tag: {model.tag}({model.description}){empty}|------ value --> {ConvertHex(data.Substring(i + 3, decValue * 2))} \n";
}
i += 3 + decValue * 2;
return TlvParser(data, i, "");
}
else
{
return TlvParser(data, i + 1, tag);
}
}
return writeFile(parser);
}
public TlvModel getTag(string tag)
{
return modelList.Find(i => i.tag == tag);
}
public string ConvertHex(string hex)
{
ascii = "";
for (int i = 0; i < hex.Length; i += 2)
{
ascii += System.Convert.ToChar(System.Convert.ToUInt32(hex.Substring(i, 2), 16));
}
return ascii;
}
private string Empty()
{
for (int s = 0; s < step; s++)
{
empty += "\t";
}
return empty;
}
public void setTag(TlvModel model)
{
modelList.Add(model);
insertTag();
}
}

Related

static_cast use to convert int to char

I have written this code to convert Decimal to binary:
string Solution::findDigitsInBinary(int A) {
if(A == 0 )
return "0" ;
else
{
string bin = "";
while(A > 0)
{
int rem = (A % 2);
bin.push_back(static_cast<char>(A % 2));
A = A/2 ;
}
reverse(bin.begin(),bin.end()) ;
return bin ;
}
}
But not getting the desired result using static_cast.
I have seen something related to this that is giving the desired result :
(char)('0'+ rem).
What's the difference between static_cast? why I am not getting the correct binary output?
With:
(char) '0' + rem;
The important difference is not the cast, but that the remainder, which always results in 0 or 1, is added to the character '0', which means that you adding a character of '0' or '1' to your string.
In your version you are adding either the integer representation of 0 or 1, but the string representations of 0 and 1 are either 48 or 49. By adding the remainder of 0 or 1 to '0' it gives a value of either 48 (character 0) or 49 (character 1).
If you do the same thing in your code it will also work.
string findDigitsInBinary(int A) {
if (A == 0)
return "0";
else
{
string bin = "";
while (A > 0)
{
int rem = (A % 2);
bin.push_back(static_cast<char>(A % 2 + '0')); // Remainder + '0'
A = A / 2;
}
reverse(bin.begin(), bin.end());
return bin;
}
Basically you should be adding characters to the string, and not numbers. So you shouldn't be adding 0 and 1 to the string, you should be adding the numbers 48 (character 0) and 49 (character 1).
This chart might illustrate better. See how the character value/digit '0' is 48 in decimal? Let's just say you wanted to add the digit 4 to the string, then because decimal 48 is 0, then you would actually want to add the decimal value of 52 to the string, 48 + 4. This is what the '0' + rem does. This is done automatically for you if you insert a character, that is, if you do:
mystring += 'A';
It will add an 'A' character to your string, but what it's actually doing in reality is converting that 'A' to decimal 65 and adding it to the string. What you have in your code is you're adding decimal numbers/integers 0 and 1, and these aren't characters in the Unicode/ASCII representation.
Now that you understand how characters are encoded, to cast an integer to a char does not change the decimal/integer to its character representation, but it changes the data type from int to char, a 4-byte data type (most likely) to a 1-byte data type. Your cast did the following:
After the modulo % operation you got a result of either 1 or 0 as an integer, let's just say you got a 1 remainder, it would look like this as an int:
00000000 00000000 00000000 00000001
After the cast to a char it would convert it to a one-byte data type, which would make it look like this:
00000001 // Now it's a one-byte data type
Whereas what a '1' digit looks like encoded as a string character is 49, which looks like this:
00110000
As for the difference between static_cast and c-style cast, the static_cast does compile-time checks and allows casts between certain types based on particular rules, whereas a c-style cast isn't as restrictive.
char a = 5;
int* p = static_cast<int*>(&a); // Will not compile
int* p2 = (int*)&a; // Will compile and run, but is discouraged as there are risks.
*p2 = 7; // You've written past the single byte char into 3 extra bytes, which is an access violation, or undefined behaviour.

Whats happening with this method?

type IntSet struct {
words []uint64
}
func (s *IntSet) Has(x int) bool {
word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0
}
Lets go through what I think is going on:
A new type is declared called IntSet. Underneath its new type declaration it is unint64 slice.
A method is created called Has(). It can only receive IntSet types, after playing around with ints she returns a bool
Before she can play she needs two ints. She stores these babies on the stack.
Lost for words
This methods purpose is to report whether the set contains the non-negative value x. Here is a the go test:
func TestExample1(t *testing.T) {
//!+main
var x, y IntSet
fmt.Println(x.Has(9), x.Has(123)) // "true false"
//!-main
// Output:
// true false
}
Looking for some guidance understanding what this method is doing inside. And why the programmer did it in such complicated means (I feel like I am missing something).
The return statement:
return word < len(s.words) && s.words[word]&(1<<bit) != 0
Are the order of operations this?
return ( word < len(s.words) && ( s.words[word]&(1<<bit)!= 0 )
And what is the [words] and & doing within:
s.words[word]&(1<<bit)!= 0
edit: Am beginning to see slightly seeing that:
s.words[word]&(1<<bit)!= 0
Is just a slice but don't understand the &
As I read the code, I scribbled some notes:
package main
import "fmt"
// A set of bits
type IntSet struct {
// bits are grouped into 64 bit words
words []uint64
}
// x is the index for a bit
func (s *IntSet) Has(x int) bool {
// The word index for the bit
word := x / 64
// The bit index within a word for the bit
bit := uint(x % 64)
if word < 0 || word >= len(s.words) {
// error: word index out of range
return false
}
// the bit set within the word
mask := uint64(1 << bit)
// true if the bit in the word set
return s.words[word]&mask != 0
}
func main() {
nBits := 2*64 + 42
// round up to whole word
nWords := (nBits + (64 - 1)) / 64
bits := IntSet{words: make([]uint64, nWords)}
// bit 127 = 1 * 64 + 63
bits.words[1] = 1 << 63
fmt.Printf("%b\n", bits.words)
for i := 0; i < nWords*64; i++ {
has := bits.Has(i)
if has {
fmt.Println(i, has)
}
}
has := bits.Has(127)
fmt.Println(has)
}
Playground: https://play.golang.org/p/rxquNZ_23w1
Output:
[0 1000000000000000000000000000000000000000000000000000000000000000 0]
127 true
true
The Go Programming Language Specification
Arithmetic operators
& bitwise AND integers
peterSO's answer is spot on - read it. But I figured this might also help you understand.
Imagine I want to store some random numbers in the range 1 - 8. After I store these numbers I will be asked if the number n (also in the range of 1 - 8) appears in the numbers I recorded earlier. How would we store the numbers?
One, probably obvious, way would be to store them in a slice or maybe a map. Maybe we would choose a map since lookups will be constant time. So we create our map
seen := map[uint8]struct{}{}
Our code might look something like this
type IntSet struct {
seen: map[uint8]struct{}
}
func (i *IntSet) AddValue(v uint8) {
i.seen[v] = struct{}{}
}
func (i *IntSet) Has(v uint8) bool {
_, ok := i.seen[v]
return ok
}
For each number we store we take up (at least) 1 byte (8 bits) of memory. If we were to store all 8 numbers we would be using 64 bits / 8 bytes.
However, as the name implies, this is an int Set. We don't care about duplicates, we only care about membership (which Has provides for us).
But there is another way we could store these numbers, and we could do it all within a single byte. Since a byte provides 8 bits, we can use these 8 bits as markers for values we have seen. The initial value (in binary notation) would be
00000000 == uint8(0)
If we did an AddValue(3) we could change the 3rd bit and end up with
00000100 == uint8(3)
^
|______ 3rd bit
If we then called AddValue(8) we would have
10000100 == uint8(132)
^ ^
| |______ 3rd bit
|___________ 8th bit
So after adding 3 and 8 to our IntSet we have the internally stored integer value of 132. But how do we take 132 and figure out whether a particular bit is set? Easy, we use bitwise operators.
The & operator is a logical AND. It will return the value of the bits common between the numbers on each side of the operator. For example
10001100 01110111 11111111
& 01110100 & 01110000 & 00000001
-------- -------- --------
00000100 01110000 00000001
So to find out if n is in our set we simply do
our_set_value & (1 << (value_we_are_looking_for - 1))
which if we were searching for 4 would yield
10000100
& 00001000
----------
0 <-- so 4 is not present
or if we were searching for 8
10000100
& 10000000
----------
10000000 <-- so 8 is present
You may have noticed I subtracted 1 from our value_we_are_looking for. This is because I am fitting 1-8 into our 8bit number. If we only wanted to store seven numbers then we could just skip using the very first bit and assume our counting starts at bit #2 then we wouldn't have to subtract 1, like the code you posted does.
Assuming you understand all of that, here's where things get interesting. So far we have been storing our values in a uint8 (so we could only have 8 values, or 7 if you omit the first bit). But there are larger numbers that have more bits, like uint64. Instead of 8 values, we can store 64 values! But what happens if the range of values we want to track exceed 1-64? What if we want to store 65? This is where the slice of words comes from in the original code.
Since the code posted skips the first bit, from now on I will do so as well.
We can use the first uint64 to store the numbers 1 - 63. When we want to store the numbers 64-127 we need a new uint64. So our slice would be something like
[ uint64_of_1-63, uint64_of_64-127, uint64_of_128-192, etc]
Now, to answer the question about whether a number is in our set we need to first find the uint64 whose range would contain our number. If we were searching for 110 we would want to use the uint64 located at index 1 (uint64_of_64-128) because 110 would fall in that range.
To find the index of the word we need to look at, we take the whole number value of n / 64. In the case of 110 we would get 1, which is exactly what we want.
Now we need to examine the specific bit of that number. The bit that needs to be checked would be the remainder when dividing 110 by 64, or 46. So if the 46th bit of the word at index 1 is set, then we have seen 110 before.
This is how it might look in code
type IntSet struct {
words []uint64
}
func (s *IntSet) Has(x int) bool {
word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0
}
func (s *IntSet) AddValue(x int) {
word := x / 64
bit := x % 64
if word < len(s.words) {
s.words[word] |= (1 << uint64(bit))
}
}
And here is some code to test it
func main() {
rangeUpper := 1000
bits := IntSet{words: make([]uint64, (rangeUpper/64)+1)}
bits.AddValue(127)
bits.AddValue(8)
bits.AddValue(63)
bits.AddValue(64)
bits.AddValue(998)
fmt.Printf("%b\n", bits.words)
for i := 0; i < rangeUpper; i++ {
if ok := bits.Has(i); ok {
fmt.Printf("Found %d\n", i)
}
}
}
OUTPUT
Found 8
Found 63
Found 64
Found 127
Found 998
Playground of above
Note
The |= is another bitwise operator OR. It means combine the two values keeping anywhere there is a 1 in either value
10000000 00000001 00000001
& 01000000 & 10000000 & 00000001
-------- -------- --------
11000000 10000001 00000001 <-- important that we
can set the value
multiple times
Using this method we can reduce the cost of storage for 65535 numbers from 131KB to just 1KB. This type of bit manipulation for set membership is very common in implementations of Bloom Filters
An IntSet represents a Set of integers. The presence in the set of any of a contiguous range of integers can be established by writing a single bit in the IntSet. Likewise, checking whether a specific integer is in the IntSet can be done by checking whether the particular integer corresponding to that bit is set.
So the code is finding the specific uint64 in the Intset corresponding to the integer:
word := x/64
and then the specific bit in that uint64:
bit := uint(x%64)
and then checking first that the integer being tested is in the range supported by the IntSet:
word < len(s.words)
and then whether the specific bit corresponding to the specific integer is set:
&& s.words[word]&(1<<bit) != 0
This part:
s.words[word]
pulls out the specific uint64 of the IntSet that tracks whether the integer in question is in the set.
&
is a bitwise AND.
(1<<bit)
means take a 1, shift it to the bit position representing the specific integer being tested.
Performing the bitwise AND between the integer in question, and the bit-shifted 1 will return a 0 if the bit corresponding to the integer is not set, and a 1 if the bit is set (meaning, the integer in question is a member of the IntSet).

find ASCII value of, 7 digit 1’s complement of a string(char) in java

I have to find ASCII value of 7 digit 1’s complement of a string(char) in java.
Thanks in advance.
OK, so let's start with the basics.
You need the one's complement on 7 bits only of the byte. Therefore it is true that, given 7 bytes only:
0x3E = 0 011 1110
0x41 = 0 100 0001
0x41 is indeed the one's complement of 0x3E.
Now, you have a problem to begin with, and that problem is that in Java, a char is not interchangeable with a byte because of character codings.
However, since your range of characters is limited to ASCII, you can use US-ASCII as an encoding. So, the first step is to:
final Charset ascii = StandardCharsets.US_ASCII;
final byte[] bytes = theInput.getBytes(ascii);
final byte[] transformedBytes = new byte[bytes.length];
byte original, transformed;
for (int index = 0; index < bytes.length; index++) {
original = bytes[index];
transformed = transformByte(original);
transformedBytes[index] = transformed;
}
return new String(transformedBytes, ascii);
And now, the transformedByte() method needs to be written.
One's complement simply consists of a bitwise not on all the bytes, but here you want to limit that to 7 bytes; the solution is therefore to first do the negation normally, and then mask with 0x7f, which is 0111 1111; this is made possible by the fact that none of your byte values have the highest bit set:
private static void transformByte(final byte original)
{
return ~original & 0x7f;
}
This can be substituted directly into the original method, it's not even worth a separate method ;)

Is it possible to convert any base to any base (range 2 to 46)

I know it is simple and possible to convert any base to any base. First, convert any base to decimal and then decimal to any other base. However, I had done this before for range 2 to 36 but never done for 2 to 46.
I don't understand what I will put after 36, because 36 means 'z' (1-10 are decimal numbers then the 26 characters of the alphabet).
Please explains what happens after 36.
Every base has a purpose. Usually we do base conversion to make complex computations simpler.
Here are some most popular bases used and their representation.
2-binary numeral system
used internally by nearly all computers, is base two. The two digits are 0 and 1, expressed from switches displaying OFF and ON respectively.
8-octal system
is occasionally used in computing. The eight digits are 0–7.
10-decimal system
the most used system of numbers in the world, is used in arithmetic. Its ten digits are 0–9.
12-duodecimal (dozenal) system
is often used due to divisibility by 2, 3, 4 and 6. It was traditionally used as part of quantities expressed in dozens and grosses.
16-hexadecimal system
is often used in computing. The sixteen digits are 0–9 followed by A–F.
60-sexagesimal system
originated in ancient Sumeria and passed to the Babylonians. It is still used as the basis of our modern circular coordinate system (degrees, minutes, and seconds) and time measuring (minutes and hours).
64-Base 64
is also occasionally used in computing, using as digits A–Z, a–z, 0–9, plus two more characters, often + and /.
256-bytes
is used internally by computers, actually grouping eight binary digits together. For reading by humans, bytes are usually shown in hexadecimal.
The octal, hexadecimal and base-64 systems are often used in computing because of their ease as shorthand for binary. For example, every hexadecimal digit has an equivalent 4 digit binary number.
Radices are usually natural numbers. However, other positional systems are possible, e.g. golden ratio base (whose radix is a non-integer algebraic number), and negative base (whose radix is negative).
Your doubt is whether we can convert any base to any other base after base exceeds 36
( # of Alphabets + # of digits = 26+ 10= 36)
Taking example of 64-Base
It uses A–Z(Upper case)(26), a–z(lower case)(26), 0–9(10), plus 2 more characters. This way the constraint of 36 is resolved.
As we have (26+26+10+2)64 symbols in 64-base for representation, we can represent any number in 64 base. Similarly for more base they use different symbols for representation.
Source: http://en.wikipedia.org/wiki/Radix
The symbols you use for digits are arbitrary. For example base64 encoding uses 'A' to represent the zero valued digit and '0' represents the digit with the value 52. In base64 the digits go through the alphabet A-Z, then the lower case alphabet a-z, then the traditional digits 0-9, and then usually '+' and '/'.
One base 60 system used these symbols:
So the symbols used are arbitrary. There's nothing that 'happens' after 36 except what you say happens for your system.
With number systems, you are allowed to play god.
Playing god
What you need to understand is, that symbols are completely arbitrary. There is no god-given rule for "what comes after 36". You are free to define whatever you like.
To encode numbers with a certain base, all you need is the following:
base-many distinct symbols
a total order on the symbols
An arbitrary example
Naturally, there's an infinite amount of possibilities to create such a symbol table for a certain base:
Θ
ェ
す
)
0
・
_
o
や
ι
You could use this, to encode numbers with base 10. Θ being the zero-element, ェ being the one, etc.
Conventions
Of course, your peers would not be too happy if you started using the above symbol table. Because the symbols are arbitrary, we need conventions. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 is a convention, as are the symbols we use for hexadecimal, binary, etc. It is generally agreed upon what symbol table we use for what basis, that is why we can read the numbers someone else writes down.
The important thing to remember is that all numbers are symbolic of a value. Thus if you wanted to do that, you could just make a list containing the values at each position. After base 36, you simply run out of characters you can make a logical sequence out of. For example, if you used the Cambodian Alphabet with 70 odd characters, you could do base 80.
Here is the complete code I have written, hope this will help.
import java.util.Scanner;
/*
* author : roottraveller, nov 4th 2017
*/
public class BaseXtoBaseYConversion {
BaseXtoBaseYConversion() {
}
public static String convertBaseXtoBaseY(String inputNumber, final int inputBase, final int outputBase) {
int decimal = baseXToDecimal(inputNumber, inputBase);
return decimalToBaseY(decimal, outputBase);
}
private static int baseXNumeric(char input) {
if (input >= '0' && input <= '9') {
return Integer.parseInt(input + "");
} else if (input >= 'a' && input <= 'z') {
return (input - 'a') + 10;
} else if (input >= 'A' && input <= 'Z') {
return (input - 'A') + 10;
} else {
return Integer.MIN_VALUE;
}
}
public static int baseXToDecimal(String input, final int base) {
if(input.length() <= 0) {
return Integer.MIN_VALUE;
}
int decimalValue = 0;
int placeValue = 0;
for (int index = input.length() - 1; index >= 0; index--) {
decimalValue += baseXNumeric(input.charAt(index)) * (Math.pow(base, placeValue));
placeValue++;
}
return decimalValue;
}
private static char baseYCharacter(int input) {
if (input >= 0 && input <= 9) {
String str = String.valueOf(input);
return str.charAt(0);
} else {
return (char) ('a' + (input - 10));
//return ('A' + (input - 10));
}
}
public static String decimalToBaseY(int input, int base) {
String result = "";
while (input > 0) {
int remainder = input % base;
input = input / base;
result = baseYCharacter(remainder) + result; // Important, Notice the reverse order here
}
return result;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter : number baseX baseY");
while(true) {
String inputNumber = scanner.next();
int inputBase = scanner.nextInt();
int outputBase = scanner.nextInt();
String outputNumber = convertBaseXtoBaseY(inputNumber, inputBase, outputBase);
System.out.println("Result = " + outputNumber);
}
}
}

What is the best algorithm to find whether an anagram is of a palindrome?

In this problem we consider only strings of lower-case English letters (a-z).
A string is a palindrome if it has exactly the same sequence of characters when traversed left-to-right as right-to-left. For example, the following strings are palindromes:
"kayak"
"codilitytilidoc"
"neveroddoreven"
A string A is an anagram of a string B if it consists of exactly the same characters, but possibly in another order. For example, the following strings are each other's anagrams:
A="mary" B="army" A="rocketboys" B="octobersky" A="codility" B="codility"
Write a function
int isAnagramOfPalindrome(String S);
which returns 1 if the string s is a anagram of some palindrome, or returns 0 otherwise.
For example your function should return 1 for the argument "dooernedeevrvn", because it is an anagram of a palindrome "neveroddoreven". For argument "aabcba", your function should return 0.
'Algorithm' would be too big word for it.
You can construct a palindrome from the given character set if each character occurs in that set even number of times (with possible exception of one character).
For any other set, you can easily show that no palindrome exists.
Proof is simple in both cases, but let me know if that wasn't clear.
In a palindrome, every character must have a copy of itself, a "twin", on the other side of the string, except in the case of the middle letter, which can act as its own twin.
The algorithm you seek would create a length-26 array, one for each lowercase letter, and start counting the characters in the string, placing the quantity of character n at index n of the array. Then, it would pass through the array and count the number of characters with an odd quantity (because one letter there does not have a twin). If this number is 0 or 1, place that single odd letter in the center, and a palindrome is easily generated. Else, it's impossible to generate one, because two or more letters with no twins exist, and they can't both be in the center.
I came up with this solution for Javascript.
This solution is based on the premise that a string is an anagram of a palindrome if and only if at most one character appears an odd number of times in it.
function solution(S) {
var retval = 0;
var sorted = S.split('').sort(); // sort the input characters and store in
// a char array
var array = new Array();
for (var i = 0; i < sorted.length; i++) {
// check if the 2 chars are the same, if so copy the 2 chars to the new
// array
// and additionally increment the counter to account for the second char
// position in the loop.
if ((sorted[i] === sorted[i + 1]) && (sorted[i + 1] != undefined)) {
array.push.apply(array, sorted.slice(i, i + 2));
i = i + 1;
}
}
// if the original string array's length is 1 or more than the length of the
// new array's length
if (sorted.length <= array.length + 1) {
retval = 1;
}
//console.log("new array-> " + array);
//console.log("sorted array-> " + sorted);
return retval;
}
i wrote this code in java. i don't think if its gonna be a good one ^^,
public static int isAnagramOfPalindrome(String str){
ArrayList<Character> a = new ArrayList<Character>();
for(int i = 0; i < str.length(); i++){
if(a.contains(str.charAt(i))){
a.remove((Object)str.charAt(i));
}
else{
a.add(str.charAt(i));
}
}
if(a.size() > 1)
return 0;
return 1;
}
Algorithm:
Count the number of occurrence of each character.
Only one character with odd occurrence is allowed since in a palindrome the maximum number of character with odd occurrence can be '1'.
All other characters should occur in an even number of times.
If (2) and (3) fail, then the given string is not a palindrome.
This adds to the other answers given. We want to keep track of the count of each letter seen. If we have more than one odd count for a letter then we will not be able to form a palindrome. The odd count would go in the middle, but only one odd count can do so.
We can use a hashmap to keep track of the counts. The lookup for a hashmap is O(1) so it is fast. We are able to run the whole algorithm in O(n). Here's it is in code:
if __name__ == '__main__':
line = input()
dic = {}
for i in range(len(line)):
ch = line[i]
if ch in dic:
dic[ch] += 1
else:
dic[ch] = 1
chars_whose_count_is_odd = 0
for key, value in dic.items():
if value % 2 == 1:
chars_whose_count_is_odd += 1
if chars_whose_count_is_odd > 1:
print ("NO")
else:
print ("YES")
I have a neat solution in PHP posted in this question about complexities.
class Solution {
// Function to determine if the input string can make a palindrome by rearranging it
static public function isAnagramOfPalindrome($S) {
// here I am counting how many characters have odd number of occurrences
$odds = count(array_filter(count_chars($S, 1), function($var) {
return($var & 1);
}));
// If the string length is odd, then a palindrome would have 1 character with odd number occurrences
// If the string length is even, all characters should have even number of occurrences
return (int)($odds == (strlen($S) & 1));
}
}
echo Solution :: isAnagramOfPalindrome($_POST['input']);
It uses built-in PHP functions (why not), but you can make it yourself, as those functions are quite simple. First, the count_chars function generates a named array (dictionary in python) with all characters that appear in the string, and their number of occurrences. It can be substituted with a custom function like this:
$count_chars = array();
foreach($S as $char) {
if array_key_exists($char, $count_chars) {
$count_chars[$char]++;
else {
$count_chars[$char] = 1;
}
}
Then, an array_filter with a count function is applied to count how many chars have odd number of occurrences:
$odds = 0;
foreach($count_chars as $char) {
$odds += $char % 2;
}
And then you just apply the comparison in return (explained in the comments of the original function).
return ($odds == strlen($char) % 2)
This runs in O(n). For all chars but one, must be even. the optional odd character can be any odd number.
e.g.
abababa
def anagram_of_pali(str):
char_list = list(str)
map = {}
nb_of_odds = 0
for char in char_list:
if char in map:
map[char] += 1
else:
map[char] = 1
for char in map:
if map[char] % 2 != 0:
nb_of_odds += 1
return True if nb_of_odds <= 1 else False
You just have to count all the letters and check if there are letters with odd counts. If there are more than one letter with odd counts the string does not satisfy the above palindrome condition.
Furthermore, since a string with an even number letters must not have a letter with an odd count it is not necessary to check whether string length is even or not. It will take O(n) time complexity:
Here's the implementation in javascript:
function canRearrangeToPalindrome(str)
{
var letterCounts = {};
var letter;
var palindromeSum = 0;
for (var i = 0; i < str.length; i++) {
letter = str[i];
letterCounts[letter] = letterCounts[letter] || 0;
letterCounts[letter]++;
}
for (var letterCount in letterCounts) {
palindromeSum += letterCounts[letterCount] % 2;
}
return palindromeSum < 2;
}
All right - it's been a while, but as I was asked such a question in a job interview I needed to give it a try in a few lines of Python. The basic idea is that if there is an anagram that is a palindrome for even number of letters each character occurs twice (or something like 2n times, i.e. count%2==0). In addition, for an odd number of characters one character (the one in the middle) may occur only once (or an uneven number - count%2==1).
I used a set in python to get the unique characters and then simply count and break the loop once the condition cannot be fulfilled. Example code (Python3):
def is_palindrome(s):
letters = set(s)
oddc=0
fail=False
for c in letters:
if s.count(c)%2==1:
oddc = oddc+1
if oddc>0 and len(s)%2==0:
fail=True
break
elif oddc>1:
fail=True
break
return(not fail)
def is_anagram_of_palindrome(S):
L = [ 0 for _ in range(26) ]
a = ord('a')
length = 0
for s in S:
length += 1
i = ord(s) - a
L[i] = abs(L[i] - 1)
return length > 0 and sum(L) < 2 and 1 or 0
While you can detect that the given string "S" is a candidate palindrome using the given techniques, it is still not very useful. According to the implementations given,
isAnagramOfPalindrome("rrss") would return true but there is no actual palindrome because:
A palindrome is a word, phrase, number, or other sequence of symbols or elements, whose meaning may be interpreted the same way in either forward or reverse direction. (Wikipedia)
And Rssr or Srrs is not an actual word or phrase that is interpretable. Same with it's anagram. Aarrdd is not an anagram of radar because it is not interpretable.
So, the solutions given must be augmented with a heuristic check against the input to see if it's even a word, and then a verification (via the implementations given), that it is palindrome-able at all. Then there is a heuristic search through the collected buckets with n/2! permutations to search if those are ACTUALLY palindromes and not garbage. The search is only n/2! and not n! because you calculate all permutations of each repeated letter, and then you mirror those over (in addition to possibly adding the singular pivot letter) to create all possible palindromes.
I disagree that algorithm is too big of a word, because this search can be done pure recursively, or using dynamic programming (in the case of words with letters with occurrences greater than 2) and is non trivial.
Here's some code: This is same as the top answer that describes algorithm.
1 #include<iostream>
2 #include<string>
3 #include<vector>
4 #include<stack>
5
6 using namespace std;
7
8 bool fun(string in)
9 {
10 int len=in.size();
11 int myints[len ];
12
13 for(int i=0; i<len; i++)
14 {
15 myints[i]= in.at(i);
16 }
17 vector<char> input(myints, myints+len);
18 sort(input.begin(), input.end());
19
20 stack<int> ret;
21
22 for(int i=0; i<len; i++)
23 {
24 if(!ret.empty() && ret.top()==input.at(i))
25 {
26 ret.pop();
27 }
28 else{
29 ret.push(input.at(i));
30 }
31 }
32
33 return ret.size()<=1;
34
35 }
36
37 int main()
38 {
39 string input;
40 cout<<"Enter word/number"<<endl;
41 cin>>input;
42 cout<<fun(input)<<endl;
43
44 return 0;
45 }

Resources