How can I extract the MCC and MNC from a PLMN? - gsm

I am running the AT command AT+KCELL to get cell information and it returns, amongst other things, a PLMN (Public Land and Mobile Network) - the description of this from the documentation is:
PLMN identifiers (3 bytes), made of MCC (Mobile Country Code), and MNC
(Mobile Network Code).
OK, that matches what Wikipedia says - in there is the MCC and MNC. Now what I don't understand is how do I extract the aforementioned MCC and MNC values?
Here is an example. I get back:
32f210
and I am told (though I am sceptical) that that should result in:
MNC: 1
MCC: 232
but I can't for the life of me work out how to get that result from the PLMN so how do I parse this?

Well, I have found this out and figured I would add an answer here in case there is some other unlucky soul who has to do this - the PDF called GSM Technical Specification (section 10.2.4) contains the answer, the relevant bit is:
PLMN Contents: Mobile Country Code (MCC) followed by the Mobile Network Code (MNC). Coding: according to TS GSM 04.08 [14].
If storage
for fewer than the maximum possible number n is required, the excess
bytes shall be set to 'FF'. For instance, using 246 for the MCC and 81
for the MNC and if this is the first and only PLMN, the contents reads
as follows: Bytes 1-3: '42' 'F6' '18' Bytes 4-6: 'FF' 'FF' 'FF' etc.
So I was wrong to be sceptical!
I need to read from the left swapping the digits around so the first two bytes would be the MCC so that would be 232f and the MNC would be 01 then I just discard the f and I have 232 and 1! Glad that one is sorted.
For example, in c# you can do it like this:
string plmn = "whatever the plmn is";
string mcc = new string(plmn.Substring(0, 2).Reverse().ToArray())
+ new string(plmn.Substring(2, 2).Reverse().ToArray())
.Replace('f', ' ')
.Trim();
string mnc = new string(plmn.Substring(4, 2).Reverse().ToArray())
.Replace('f', ' ')
.Trim();

Here is a java answer with bitwise operations:
public static String mcc(byte[] plmnId) {
if (plmnId == null || plmnId.length != 3)
throw new IllegalArgumentException(String.format("Wrong plmnid %s", Arrays.toString(plmnId)));
int a1 = plmnId[0] & 0x0F;
int a2 = (plmnId[0] & 0xF0) >> 4;
int a3 = plmnId[1] & 0x0F;
return "" + a1 + a2 + a3;
}
public static String mnc(byte[] plmnId) {
if (plmnId == null || plmnId.length != 3)
throw new IllegalArgumentException(String.format("Wrong plmnid %s", Arrays.toString(plmnId)));
int a1 = plmnId[2] & 0x0F;
int a2 = (plmnId[2] & 0xF0) >> 4;
int a3 = (plmnId[1] & 0xF0) >> 4;
if (a3 == 15)
return "" + a1 + a2;
else
return "" + a1 + a2 + a3;
}

Related

The encryption won't decrypt

I was given an encrypted copy of the study guide here, but how do you decrypt and read it???
In a file called pa11.py write a method called decode(inputfile,outputfile). Decode should take two parameters - both of which are strings. The first should be the name of an encoded file (either helloworld.txt or superdupertopsecretstudyguide.txt or yet another file that I might use to test your code). The second should be the name of a file that you will use as an output file.
Your method should read in the contents of the inputfile and, using the scheme described in the hints.txt file above, decode the hidden message, writing to the outputfile as it goes (or all at once when it is done depending on what you decide to use).
The penny math lecture is here.
"""
Program: pennyMath.py
Author: CS 1510
Description: Calculates the penny math value of a string.
"""
# Get the input string
original = input("Enter a string to get its cost in penny math: ")
cost = 0
Go through each character in the input string
for char in original:
value = ord(char) #ord() gives us the encoded number!
if char>="a" and char<="z":
cost = cost+(value-96) #offset the value of ord by 96
elif char>="A" and char<="Z":
cost = cost+(value-64) #offset the value of ord by 64
print("The cost of",original,"is",cost)
Another hint: Don't forget about while loops...
Another hint: After letters -
skip ahead by their pennymath value positions + 2
After numbers - skip ahead by their number + 7 positions
After anything else - just skip ahead by 1 position
The issue I'm having in that I cant seem to get the coding right to decode the file it comes out looking the same. This is the current code I have been using. But once I try to decrypt the message it stays the same.
def pennycost(c):
if c >="a" and c <="z":
return ord(c)-96
elif c>="A" and c<="Z":
return ord(c)-64
def decryption(inputfile,outputfile):
with open(inputfile) as f:
fo = open(outputfile,"w")
count = 0
while True:
c = f.read(1)
if not c:
break;
if count > 0:
count = count -1;
continue
elif c.isalpha():
count = pennycost(c)
fo.write(c)
elif c.isdigit():
count = int(c)
fo.write(c)
else:
count = 6
fo.write(c)
fo.close()
inputfile = input("Please enter the input file name: ")
outputfile = input("Plese enter the output file name(EXISTING FILE WILL BE OVER WRITTEN!): ")
decryption(inputfile,outputfile)

How to Get ECI from ECGI

I have ecgi of a lte cell I need to get plmn and and eci out it.
I can get plmn by doing right shift
plmn = ecgi >>28
I have not idea how to get eci from ecgi.
ECGI = MCC + MNC + eNodeB id + Cell id
The latter two are ECI (eNodeB id + Cell id) -> 28 least bits.
That is ECI = ECGI & 0xFFFFFFF

QT regularExpressions retrieve numbers

I've to split simple QStrings of the form "number number number",for example " 2323 432 1223".
The code i use is
QString line;
QRegularExpression re("(\\d+)");
QRegularExpressionMatch match;
while(!qtextstream.atEnd()){
line = qtextstream.readLine();
match = re.match(line);
std::cout<<"1= "<<match.captured(0).toUtf8().constData()<<std::endl;
std::cout<<"2= "<<match.captured(1).toUtf8().constData()<<std::endl;
std::cout<<"3= "<<match.captured(2).toUtf8().constData()<<std::endl;
}
if the first line being processed is like the example string i get
for the first while cycle output:
1= 2323
2= 2323
3=
what is wrong?
Your regex only matches 1 or more digits once with re.match. The first two values are Group 0 (the whole match) and Group 1 value (the value captured with a capturing group #1). Since there is no second capturing group in your pattern, match.captured(2) is empty.
You must use QRegularExpressionMatchIterator to get all matches from the current string:
QRegularExpressionMatchIterator i = re.globalMatch(line);
while (i.hasNext()) {
qDebug() << i.next().captured(1); // or i.next().captured(0) to see the whole match
}
Note that (\\d+) contains an unnecessary capturing group, since the whole match can be accessed, too. So, you may use re("\\d+") and then get the whole match with i.next().captured(0).
If the usage of regular expressions isn't mandatory, you could also use QString's split()-function.
QString str("2323 432 1223");
QStringList list = str.split(" ");
for(int i = 0; i < list.length(); i++){
qDebug() << list.at(i);
}

symbols being printed when english alphabet wanted

I am writing this code and have recently come across an error. I have no idea why this is happening. In theory, the english alphabet should be being printed. However, instead of the english alphabet, symbols are being printed instead.
I can not paste the symbols for some reason, but if you ran the code yourself, you'll understand what I mean.
My full code is posted below.
alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFHIJKLMNOPQRSTUVWXYZ0123456789"
choice = input("Would you like to encrypt or decrypt? [e/d]: ")
if choice == "e":
message = input("Please insert the message you would like to use: ")
keyword = input("Please insert the keyword you would like to use: ")
ik = len(keyword)
i = 0
string = ''
for A in message:
message1 = (ord(A)) - 96
key1 = (ord(keyword[i])) - 96
addition = message1 + key1
string += (chr(addition))
if i >= ik:
i = 0
else:
i += 1
print (string)
You need to add back the 96 you originally took away :) Alternatively, use the Caesar cipher formula as adding back 96 will still result in symbols appearing (I did the ocr coursework already)
addition = message1 + key1 + 96
your code will not work if the keyword is shorter than the message, so use the modulo operator (%) on i with the length of the keyword inside the line:
key1 = (ord(keyword[i])) - 96

decoding an ASCII character message

I have no idea what im doing I need to decode mmZ\dxZmx]Zpgy, I have an example but not sure what to do please help!
If (EncryptedChar - Key < 32) then
DecryptedChar = ((EncryptedChar - Key) + 127) - 32
Else
DecryptedChar = (EncryptedChar - Key)
the key us unknown 1-100
Use ord and chr to convert between the ordinals (ord) of the ASCII value and the and the characters (chr) they represent.
Then you can loop through your string and apply the your algorithm to each.
For example:
import sys
SecretMessage = "mmZ\dxZmx]Zpgy"
Key = 88
for Letter in SecretMessage:
EncryptedChar = ord(Letter)
if (EncryptedChar - Key) < 32:
DecryptedChar = ((EncryptedChar - Key) + 127) - 32
else:
DecryptedChar = (EncryptedChar - Key)
sys.stdout.write(chr(DecryptedChar))
Run this to see the output. I'll leave the exercise of finding the key value 88 up to you (hint: it involves iterations). You also appear to be missing the first letter from SecretMessage (probably a :).

Resources