How to send NRPN messages with pygame midi - python

I'm writing a program that will read incoming cc messages from a device that can only send cc's and send it to another device as an nrpn message. I know how to send cc messages from pygame but I can't wrap my mind around how to send nrpn's. I looked at the Vriareon code and I don't see anywhere in there were it even accesses midi. Can anyone give an example of how this is done?
Thank you!

NRPN messages are CC messages.
However, NRPN numbers are distinct from CC numbers. The MIDI specification says:
Controller number 6 (Data Entry), in conjunction with Controller numbers 96 (Data Increment), 97 (Data Decrement), 98 (Non-Registered Parameter Number LSB), 99 (Non-Registered Parameter Number MSB), 100 (Registered Parameter Number LSB), and 101 (Registered Parameter Number MSB), extend the number of controllers available via MIDI. Parameter data is transferred by first selecting the parameter number to be edited using controllers 98 and 99 or 100 and 101, and then adjusting the data value for that parameter using controller number 6, 96, or 97.
To change a controller like volume (7), you would send a single message:
B0 07 xx
To change an NRPN, you would select the NRPN first:
B0 63 mm
B0 62 ll
And then change the currently selected NRPN with the data entry controller:
B0 06 mm
B0 26 ll (optional, for 14-bit values)
So setting NRPN 0:1 to value 42 could be done with:
self.midi_out.write_short(0xb0, 0x63, 0)
self.midi_out.write_short(0xb0, 0x62, 1)
self.midi_out.write_short(0xb0, 0x06, 42)

Related

Decoding the received data from ATM90E32AS energy meter IC

I wrote a python code (raspberry pi) to receive voltage, current and power values from ATM90E32AS energy meter IC. Iam using spidev library for SPI communication with the energy meter IC. I initialized two bytearrays (each 4 bytes wide) for reading and writing the energy meter IC like
writeBuffer = bytearray ([0x00,0x00,0x00,0x00])
readBuffer = bytearray ([0x00,0x00,0x00,0x00])
For example reading active R phase voltage i initialized the register values like
VrRead_Reg = bytearray ([0x80, 0xD9])
And i try to write the above value to the IC using following subroutine to read the R phase voltage
def Vr_read():
writeBuffer[0] = VrRead_Reg[0]
writeBuffer[1] = VrRead_Reg[1]
#print(writeBuffer)
readBuffer = spi.xfer(writeBuffer)
print("Vr:",readBuffer)
time.sleep(0.5)
And iam getting the output like
Vr: [255,255,89,64]
Vr: [255,255,89,170]
Vr: [255,255,89,220]
Vr: [255,255,89,1]
Vr: [255,255,89,10]
I measured the voltage at mains it shows 230V. Then i try to match the above output with the measured voltage. Here the third byte 89 corresponds to 230V. Then i used a variac to change the voltage this time for 220V the third byte value becomes 85 and for 210V its 81 and for 100V it was 39 and so on.
I don't know how to relate 89 with 230V and also about other bytes. Plz help to decode the above output.
Do some ratio calculation:
(consider the max value of a byte is 255)
255 / 89 * 230 = 658.99 (approximately 660V)
85 / 255 * 660 = 220(220V)
81 / 255 * 660 = 209.65(210V)
39 / 255 * 660 = 100.94(100V)
But you had better find the device manual to get reference.

rand and rands implementation in python

I need an implementation of rand and rands from c++ in python to re-encrypt a bunch of files. But can't seem to get it right.
I have a exe that un-encrypts a file into text, I also have to source code, after editing the file I need to encrypt it using the same method.
Since I don't know how to write c++ code, I opted to write in python. Trying first to decrypt it to know the method is the same.
The following code is the c++ code that un-encrypted the files, where "buff" is the beginning of the encrypted block and "len" length of said block.
static const char KEY[] = "KF4QHcm2";
static const unsigned long KEY_LEN = sizeof(KEY) - 1;
void unobfuscate(unsigned char* buff, unsigned long len) {
srand((char)buff[len - 1]);
for (unsigned long i = 0; i < len - 2; i += 2) {
buff[i] ^= KEY[rand() % KEY_LEN];
}
}
From what I understand it takes the last character of the encrypted block as the seed, and from the beginning every 2 bytes it xors the value with an element of the KEY array, this index is determined by the remainder of a random number divided by the KEY length.
Searching around the web, I find that c++ uses a simple Linear Congruential Generator that shouldn't be used for encryption, but can't seem to make it work.
I found one example of the code and tried to implement the other but either don't seem to work.
#My try at implementing it
def rand():
global seed
seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)
return seed
I also read that the rand function is between 0 and RAND_MAX, but can't find the value of RAND_MAX, if I found it maybe random.randrange() could be used.
It can also be the way I set the seed since it seems in c++ a char works but in python I'm setting it to the value of the character.
Here is what I observe when un-encrypting the file using the various methods. This is just the first 13 bytes, so if someone needs to check if it works it is possible to do so.
The block ends with the sequence: 4C 0A 54 C4 this means C4 is the seed
Example encrypted:
77 43 35 69 26 6B 0C 6E 3A 74 4B 33 71 wC5i&k.n:tK3q
Example un-encrypted using c++:
24 43 6C 69 63 6B 49 6E 69 74 0A 33 34 $ClickInit.34
Example un-encrypted using python example:
1A 43 7E 69 77 6B 38 6E 0E 74 1A 33 3A .C~iwk8n.t.3:
Example un-encrypted using python implementation:
3C 43 73 69 6E 6B 4A 6E 0E 74 1A 33 37 <CsinkJn.t.37
I can also have something wrong in my python script, so here is the file in case it has any errors:
import os
def srand(s):
global seed
seed = s
def rand():
global seed
#Example code
#seed = (seed * 214013 + 2531011) % 2**64
#return (seed >> 16)&0x7fff
#Implementation code
seed = (((seed * 1103515245) + 12345) & 0x7FFFFFFF)
return seed
KEY = ['K','F','4','Q','H','c','m','2']
KEY_LEN = len(KEY) - 1
for filename in os.listdir("."):
if filename.endswith(".dat"):
print(" Decoding " + filename)
#open file
file = open(filename, "rb")
#set file attributes
file_length = os.path.getsize(filename)
file_buffer = [0] * file_length
#copy contents of file to array
for i in range(file_length):
file_buffer[i] = int.from_bytes(file.read(1), 'big')
#close file
file.close()
print(" Random Seed: " + chr(file_buffer[-1]))
#set random generator seed
srand(file_buffer[-1])
#decrypt the file
for i in range(3600, file_length, 2):
file_buffer[i] ^= ord(KEY[rand() % KEY_LEN])
#print to check if output is un-encrypted
for i in range(3600, 3613, 1):
print(file_buffer[i])
print(chr(file_buffer[i]))
continue
else:
#Do not try to un-encrypt the python script
print("/!\ Can't decode " + filename)
continue
If anyone can help me figure this out I would be grateful, if possible I would love this to work in python but, from what I can gather, it seems like I will have to learn c++ to get it to work.
rand is not a cryptographic function.
rand's algorithm is not stable between systems compilers or anything else.
If you have no choice, your best bet is to use python-C/C++ interoperability techniques and actually run rand() and srand(). That will suck, but it will suck as much as the original code did.

How to use Python to extract packet information from hexdump?

I am working on a network project where I have hexdump of packets and I need to dissect that hexdump packet to display all the packet information.
Example : Packet Information Fields -
source address
destination address
encapsulation type
frame number
frame length
FCS
data
epoch time
We are not supposed to use file as input and output because it will increase memory utilization and might crash server.
I tried with below code but this doesn't work in my case:
# imports scapy Utility
from scapy.all import *
from scapy.utils import *
# variable to store hexdump
hexdump = '0000 49 47 87 95 4a 30 9e 9c f7 09 70 7f....'
# Initialize a 802.11 structure from raw bytes
packet = Dot11(bytearray.fromhex(hexdump))
#scapy function to view the info
packet.summary()
packet.show()
Are there any suggestions to achieve this as I am new to this technology? I might lack some proper directions to solve this.
Your hexdump value seem to include the index. Remove it:
On Scapy >= 2.4rc:
data = hex_bytes('49 47 87 95 4a 30 9e 9c f7 09 70 7f [...]'.replace(' ', ''))
Or with Python 2 and Scapy <= 2.3.3:
data = '49 47 87 95 4a 30 9e 9c f7 09 70 7f [...]'.replace(' ', '').decode('hex')
Then:
Dot11(data)

How to convert midi files to keypresses (in Python)?

I'm trying to read a MIDI file and then convert each note (midi number) to a simulated keypress on the keyboard (A,f,h,J,t...).
I'm able to read any MIDI file with the python-midi library like this:
pattern = midi.read_midifile("example.mid")
and I can also simulate keypresses with pywin32 like this:
shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys(key)
But I have no idea on how to actually convert midi numbers (that are in midi files) to keypresses.
To be more precise I'm trying to convert MIDI numbers to notes and then notes to keypresses according to virtualpiano.net (61-key) so that the program would play that piano by pressing the corresponding button on the keyboard (you can press key assist in settings of the piano to see which key is what button)
Of course I would also have to wait between keypresses but that's easy enough.
Any help is appreciated. (Windows 10 64-bit (32-bit Python 2.7))
If you take a look at the midi module that you are using, you will see that there are some constants that can be used to convert notes to their MIDI number and vice versa.
>>> import midi
>>> midi.C_0 # note C octave 0
0
>>> midi.G_3 # G octave 3
43
>>> midi.Gs_4 # G# octave 4
56
>>> midi.A_8 # A octave 8
105
>>> midi.NOTE_VALUE_MAP_SHARP[0]
C_0
>>> midi.NOTE_VALUE_MAP_SHARP[56]
Gs_4
>>> midi.NOTE_VALUE_MAP_SHARP[105]
A_8
Opening a MIDI file with read_midifile() returns a Pattern object which looks like this (taken from the examples):
>>> midi.read_midifile('example.mid')
midi.Pattern(format=1, resolution=220, tracks=\
[midi.Track(\
[midi.NoteOnEvent(tick=0, channel=0, data=[43, 20]),
midi.NoteOffEvent(tick=100, channel=0, data=[43, 0]),
midi.EndOfTrackEvent(tick=1, data=[])])])
The NoteOnEvent contains timing, MIDI number/pitch and velocity which you can retrieve:
>>> on = midi.NoteOnEvent(tick=0, channel=0, data=[43, 20])
>>> on.pitch
43
>>> midi.NOTE_VALUE_MAP_SHARP[on.pitch]
'G_3'
Now all of that is interesting, but you don't really need to convert the MIDI number to a note, you just need to convert it to the keyboard key for that note as used by http://virtualpiano.net/.
Middle C is equal to MIDI 60 and this note corresponds to the 25th key on the virtualpiano keyboard which is activated by pressing the letter t. The next note, Cs_5, is MIDI 61 which is uppercase T (<shift>-t). From there you can work out the mapping for the MIDI numbers to the supported virtualpiano keys; it's this:
midi_to_vk = (
[None]*36 +
list('1!2#34$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm') +
[None]*31
)
The next problem that you will face is sending the key events. Note that in MIDI multiple notes can be played simultaneously, or can overlap in time. This means that you might need to be able to send more than one key press event at the same time.
I don't think that you can handle the velocity using a computer keyboard. There is also the issue of timing, but you said that that's not a problem for you.
Check this question first. This is general idea on how to simulate keypresses, it may look a lot but it's just a big list of keys. Then to convert midi to keyboard buttons you would create a dictionary mapping between notes and Keyboard buttons.
I understand that what you really need is a way to convert a midi note number to a note in standard notation.
Here are some elements from Wikipedia:
... GM specifies that note number 69 plays A440, which in turn fixes middle C as note number 60 ...
(from MIDI - General MIDI
Converting from midi note number (d) to frequency (f) is given by the following formula: f = 2 (d-69)/12 * 440 Hz
(from MIDI Tuning Standard - Frequency values)
And finally from C (musical note) - Designation by octave
Scientific designation |Octave name | Frequency (Hz) | Other names
C4 | One-lined | 261.626 | Middle C
So C4 is midi note 69, and midi notes are separated with a semitone(*). As you have 12 semitones in one octave, you will get C5 at midi note 81, and the famous A440 (midi note 69) is A4 in scientific notation.
As an example for the table
Midi note | Scientific notation
60 | C4
62 | D4
64 | E4
65 | F4
67 | G4
69 | A4
70 | B4
71 | C5
And you would get F♯4 at midi 66...
(*) it is musically what is called equal temperament. Midi allows for finer pitch definition but it would be far beyond this answer.

How do you verify an RSA SHA1 signature in Python?

I've got a string, a signature, and a public key, and I want to verify the signature on the string. The key looks like this:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----
I've been reading the pycrypto docs for a while, but I can't figure out how to make an RSAobj with this kind of key. If you know PHP, I'm trying to do the following:
openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA1);
Also, if I'm confused about any terminology, please let me know.
Use M2Crypto. Here's how to verify for RSA and any other algorithm supported by OpenSSL:
pem = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----""" # your example key
from M2Crypto import BIO, RSA, EVP
bio = BIO.MemoryBuffer(pem)
rsa = RSA.load_pub_key_bio(bio)
pubkey = EVP.PKey()
pubkey.assign_rsa(rsa)
# if you need a different digest than the default 'sha1':
pubkey.reset_context(md='sha1')
pubkey.verify_init()
pubkey.verify_update('test message')
assert pubkey.verify_final(signature) == 1
The data between the markers is the base64 encoding of the ASN.1 DER-encoding of a PKCS#8 PublicKeyInfo containing an PKCS#1 RSAPublicKey.
That is a lot of standards, and you will be best served with using a crypto-library to decode it (such as M2Crypto as suggested by joeforker). Treat the following as some fun info about the format:
If you want to, you can decode it like this:
Base64-decode the string:
30819f300d06092a864886f70d010101050003818d0030818902818100df1b822e14eda1fcb74336
6a27c06370e6cad69d4116ce806b3d117534cf0baa938c0f8e4500fb59d4d98fb471a8d01012d54b
32244197c7434f27c1b0d73fa1b8bae55e70155f907879ce9c25f28a9a92ff97de1684fdaff05dce
196ae76845f598b328c5ed76e0f71f6a6b7448f08691e6a556f5f0d773cb20d13f629b6391020301
0001
This is the DER-encoding of:
0 30 159: SEQUENCE {
3 30 13: SEQUENCE {
5 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
16 05 0: NULL
: }
18 03 141: BIT STRING 0 unused bits, encapsulates {
22 30 137: SEQUENCE {
25 02 129: INTEGER
: 00 DF 1B 82 2E 14 ED A1 FC B7 43 36 6A 27 C0 63
: 70 E6 CA D6 9D 41 16 CE 80 6B 3D 11 75 34 CF 0B
: AA 93 8C 0F 8E 45 00 FB 59 D4 D9 8F B4 71 A8 D0
: 10 12 D5 4B 32 24 41 97 C7 43 4F 27 C1 B0 D7 3F
: A1 B8 BA E5 5E 70 15 5F 90 78 79 CE 9C 25 F2 8A
: 9A 92 FF 97 DE 16 84 FD AF F0 5D CE 19 6A E7 68
: 45 F5 98 B3 28 C5 ED 76 E0 F7 1F 6A 6B 74 48 F0
: 86 91 E6 A5 56 F5 F0 D7 73 CB 20 D1 3F 62 9B 63
: 91
157 02 3: INTEGER 65537
: }
: }
: }
For a 1024 bit RSA key, you can treat "30819f300d06092a864886f70d010101050003818d00308189028181" as a constant header, followed by a 00-byte, followed by the 128 bytes of the RSA modulus. After that 95% of the time you will get 0203010001, which signifies a RSA public exponent of 0x10001 = 65537.
You can use those two values as n and e in a tuple to construct a RSAobj.
A public key contains both a modulus(very long number, can be 1024bit, 2058bit, 4096bit) and a public key exponent(much smaller number, usually equals one more than a two to some power). You need to find out how to split up that public key into the two components before you can do anything with it.
I don't know much about pycrypto but to verify a signature, take the hash of the string. Now we must decrypt the signature. Read up on modular exponentiation; the formula to decrypt a signature is message^public exponent % modulus. The last step is to check if the hash you made and the decrypted signature you got are the same.
I think ezPyCrypto might make this a little easier. The high-level methods of the key class includes these two methods which I hope will solve your problem:
verifyString - verify a string against a signature
importKey - import public key (and possibly private key too)
Rasmus points out in the comments that verifyString is hard-coded to use MD5, in which case ezPyCryto can't help Andrew unless he wades into its code. I defer to joeforker's answer: consider M2Crypto.
More on the DER decoding.
DER encoding always follows a TLV triplet format: (Tag, Length, Value)
Tag specifies the type (i.e. data structure) of the value
Length specifies the number of byte this value field occupies
Value is the actual value which could be another triplet
Tag basically tells how to interpret the bytes data in the Value field. ANS.1 does have a type system, e.g. 0x02 means integer, 0x30 means sequence (an ordered collection of one or more other type instances)
Length presentation has a special logic:
If the length < 127, the L field only uses one byte and coded as the
length number value directly
If the length > 127, then in the first byte of L field, the first bit
must be 1, and the rest 7 bits represents the number of following
bytes used to specifies the length of the Value field. Value, the
actually bytes of the value itself.
For example, say I want to encode a number of 256 bytes long, then it would be like this
02 82 01 00 1F 2F 3F 4F … DE AD BE EF
Tag, 0x02 means it's a number
Length, 0x82, bit presentation of it is 1000 0010, meaning the
following two bytes specifies the actually length of the value, which
his 0x0100 meaning the value field is 256 bytes long
Value, from 1F to EF, the actual 256 bytes.
Now looking at your example
30819f300d06092a864886f70d010101050003818d0030818902818100df1b822e14eda1fcb74336
6a27c06370e6cad69d4116ce806b3d117534cf0baa938c0f8e4500fb59d4d98fb471a8d01012d54b
32244197c7434f27c1b0d73fa1b8bae55e70155f907879ce9c25f28a9a92ff97de1684fdaff05dce
196ae76845f598b328c5ed76e0f71f6a6b7448f08691e6a556f5f0d773cb20d13f629b6391020301
0001
It interprets as just what Rasmus Faber put in his reply
Maybe this isn't the answer you're looking for, but if all you need is to turn the key into bits, it looks like it's Base64 encoded. Look at the codecs module (I think) in the standard Python library.
Using M2Crypto, the above answers does not work. Here is a tested example.
import base64
import hashlib
import M2Crypto as m2
# detach the signature from the message if it's required in it (useful for url encoded data)
message_without_sign = message.split("&SIGN=")[0]
# decode base64 the signature
binary_signature = base64.b64decode(signature)
# create a pubkey object with the public key stored in a separate file
pubkey = m2.RSA.load_pub_key(os.path.join(os.path.dirname(__file__), 'pubkey.pem'))
# verify the key
assert pubkey.check_key(), 'Key Verification Failed'
# digest the message
sha1_hash = hashlib.sha1(message_without_sign).digest()
# and verify the signature
assert pubkey.verify(data=sha1_hash, signature=binary_signature), 'Certificate Verification Failed'
And that's about it
I try the code given by joeforker but it does not work.
Here is my example code and it works fine.
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA
pem = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----""" # your example key
key = RSA.importKey(pem)
h = SHA.new(self.populateSignStr(params))
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
print "verified"
else:
print "not verified"

Categories