I am working at printing an image to a thermal printer. The image needs to be converted into an unsigned char buffer. For example
unsigned char buffer[10]={0x55,0x66,0x77,0x88,0x44, 0x1B,0x58,0x31,0x15,0x1D}
So far I can covert the image to a black and white version and then loop through it to get each hexadecimal value as an NSString stored in an NSMutableArray. Like below when outputted in the NSLog
( 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
I need to be able to loop through the array and retrieve each hex value stored as a string and convert it into an unsigned char so I can add it to my buffer to print
Byte buffer[hexStringArray count];
for (int i=0;i=[hexStringArray count];i++)//add print content
{
buffer[i] = [hexStringArray objectAtIndex:i] // this from string to hex to unsigned char;
}
[sessionController writeData:[NSData dataWithBytes:buffer length:[hexStringArray count]];
How can I convert an NSString hex value into an actual hex, which can then be converted into an unsigned char.
Related
I am trying to implement a simple WiFi deauther using my nodemcu but i can't see any disconnection b/w AP(my android's hotspot) & Station ( my second android device)
But when i am using a third party tool like Wi-PWN ( available on GitHub ) , is working.
So its clear that i am doing something wrong in Deauthentication process
Here is some parts of code
// Channel to perform deauth
uint8_t channel = 0;
// Packet buffer
uint8_t packet_buffer[128];
// DeAuth template
uint8_t template_da[26] = {
0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xCC, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0x00, 0x00, 0x01,
0x00};
uint16_t create_packet(uint8_t *buf, uint8_t *client, uint8_t *ap, uint8_t type)
{
int i = 0;
memcpy(buf, template_da, 26);
// Destination
memcpy(buf + 4, client, ETH_MAC_LEN);
// Sender
memcpy(buf + 10, ap, ETH_MAC_LEN);
buf[0] = type;
return 26;
}
/* Sends deauth packets. */
void deauth(uint8_t *c, uint8_t *ap, uint16_t seq)
{
uint8_t i = 0;
uint16_t sz = 0;
sz = create_packet(packet_buffer, c, ap, 0xc0); // 0xc0 for deauth
wifi_send_pkt_freedom(packet_buffer, sz, 0);
sz = create_packet(packet_buffer, c, ap, 0xa0); // xa0 for disassociation
wifi_send_pkt_freedom(packet_buffer, sz, 0);
delay(1);
}
}
Edit : I know the mac address of both AP & Station so there could be no mistake in filling mac while creating packet.
Plain text : Encrypt and decrypt text with AES algorithm
Key (256) : testsecret
Result (https://aesencryption.net/) : iFhSyFY3yYoO2G6GVGkdhZJjD+h0Pxv5fQnO3xIarzuGQSkIxlrpSprC5bC3gJ2U
i use small code in object to decrypt this this text :
(NSData*)AES256DecryptWithKey:(NSString*)key {
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesDecrypted = 0; // char iv[kCCBlockSizeAES128 + 1]; bzero(iv, sizeof(iv)) ;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding ,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) /,
[self bytes], dataLength, / input /
buffer, bufferSize, / output */
&numBytesDecrypted);
if (cryptStatus == kCCSuccess)
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSMutableData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer); //free the buffer;
return nil; }
Result : t\PFLFC\^X\^C^\^^\^RWQV\^\ypt text with AES algorithm
Seem it alway wrong first 16bit block. Can u help me. what i'm wrong when encrypt ?
aesencryption.net performs AES in CBC mode. IV is a hardcoded ASCII string (16 chars). Message is UTF8-encoded then PKCS7-padded. AES key is the given password, UTF8-encoded then null-padded to choosen key size (or truncated if password is too long). And of course, the result is displayed as base64.
Getting the IV is as simple as encrypting a given block, decrypting it in ECB mode, and xoring that decrypted block with the original one...
Try to use AESCrypt-ObjC instead of Cryptlib Library.
Installation
Add this line to your class:
#import "AESCrypt.h"
Usage
NSString *message = #"top secret message";
NSString *password = #"p4ssw0rd";
Encrypting
NSString *encryptedData = [AESCrypt encrypt:message password:password];
Decrypting
NSString *message = [AESCrypt decrypt:encryptedData password:password];
Hope this will help.
Also, you can see this answer: https://stackoverflow.com/a/51767050/5167909
Your CCCryptorStatus parameters in osstatus :
should look like this
cryptStatus = CCCrypt( kCCDecrypt, kCCAlgorithmAES128,kCCOptionECBMode + kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256 NULL,[self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted );,
However you length of the key is less than 16 bytes. At least make sure that your secret key should be of 16 bytes.
I'm creating a Swift app in Xcode that sends a command to a BLE adapter in order to make the LED's connected to it change to a different colour.
As I've established from a reply to a previous post on SO, I have to send command in terms of hex integers in an array. I'm using the following code in order to do this:
let bytes : [UInt8] = [ 0x52, 0x13, 0x00, 0x56, 0xFF, 0x00, 0x00, 0x00, 0xAA ]
let data = NSData(bytes: bytes, length: bytes.count)
Therefore, this requires a UInt8 form as suggested above.
However, I'm trying to use sliders as colour pickers on my Swift app in order to set the R, G, and B colours of the LED strip connected to the BLE receiver. In order to do this I have created three sliders for R, G and B respectively, setting the minimum value of each to 0 and the max to 255 (since 255 converts to FF in hex). I'm then using the following function to convert these to hex form for me to implement in the command above.
func colorToHex(input: Int) -> UInt8 {
var st = NSString(format: "%2X", input)
return st
}
The problem with this is the fact that I must return a UInt8 value back again. Since 'st' is an NSString, Xcode throws an error of 'NSString not convertible to UInt8'.
I'm fairly new to Swift. The question here is, how do I get the function to return a UInt8 value how do I get it to form a UInt8 value?
Any help would be greatly appreciated!
There is no need to use NSString or Int. If redSlider is your UISlider with minimum value 0 and maximum value 255 then you can just compute
let redByte = UInt8(redSlider.value)
and use that in your bytes array:
var bytes : [UInt8] = [ 0x52, 0x13, 0x00, 0x56, 0xFF, 0x00, 0x00, 0x00, 0xAA ]
bytes[0] = redByte // Assuming that the first array element is for red.
Just
func colorToHex(input: Int) -> UInt8 {
return UInt8(input % (Int(UInt8.max) + 1))
}
NSString(format: "%2X", colorToHex(25)) // "19"
NSString(format: "%2X", colorToHex(254)) // "FE"
NSString(format: "%2X", colorToHex(255)) // "FF"
NSString(format: "%2X", colorToHex(256)) // "0"
If I were you, I will use NSString(format: "%0x", colorToHex(25)) // "19"
In your case you have space, if the number has one symbol
I am using SecKeyEncrypt with a JSON formatted string as input. If pass SecKeyEncrypt a plainTextLength of less than 246, it works. If I pass it a length of 246 or more, it fails with return value: paramErr (-50).
It could be a matter of the string itself. An example of what I might send SecKeyEncrypt is:
{"handle":"music-list","sym_key":"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALeaEO7ZrjgOFGLBzBHZtQuzH2GNDYMLWP+fIFNu5Y+59C6HECY+jt0yOXXom2mzp/WYYI/9G+Ig8OD6YiKv2nMCAwEAAQ==","app_id":"xgfdt.LibraryTestApp","api_key":"7e080f74de3625b90dd293fc8be560a5cdfafc08"}
The 245th character is '0'.
The ONLY input that is changing between this working and is the plainTextLength. SecKeyGetBlockSize() is returning 256 to me, so any input up to 256 characters long should work.
Here is my encrypt method:
+ (NSData*)encrypt:(NSString*)data usingPublicKeyWithTag:(NSString*)tag
{
OSStatus status = noErr;
size_t cipherBufferSize;
uint8_t *cipherBuffer;
// [cipherBufferSize]
size_t dataSize = 246;//[data lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const uint8_t* textData = [[data dataUsingEncoding:NSUTF8StringEncoding] bytes];
SecKeyRef publicKey = [Encryption copyPublicKeyForTag:tag];
NSAssert(publicKey, #"The public key being referenced by tag must have been stored in the keychain before attempting to encrypt data using it!");
// Allocate a buffer
cipherBufferSize = SecKeyGetBlockSize(publicKey);
// this value will not get modified, whereas cipherBufferSize may.
const size_t fullCipherBufferSize = cipherBufferSize;
cipherBuffer = malloc(cipherBufferSize);
NSMutableData* accumulatedEncryptedData = [NSMutableData dataWithCapacity:0];
// Error handling
for (int ii = 0; ii*fullCipherBufferSize < dataSize; ii++) {
const uint8_t* dataToEncrypt = (textData+(ii*fullCipherBufferSize));
const size_t subsize = (((ii+1)*fullCipherBufferSize) > dataSize) ? fullCipherBufferSize-(((ii+1)*fullCipherBufferSize) - dataSize) : fullCipherBufferSize;
// Encrypt using the public key.
status = SecKeyEncrypt( publicKey,
kSecPaddingPKCS1,
dataToEncrypt,
subsize,
cipherBuffer,
&cipherBufferSize
);
[accumulatedEncryptedData appendBytes:cipherBuffer length:cipherBufferSize];
}
if (publicKey) CFRelease(publicKey);
free(cipherBuffer);
return accumulatedEncryptedData;
}
From the documentation:
plainTextLen
Length in bytes of the data in the plainText buffer. This must be less than or equal to the value returned by the SecKeyGetBlockSize function. When PKCS1 padding is performed, the maximum length of data that can be encrypted is 11 bytes less than the value returned by the SecKeyGetBlockSize function (secKeyGetBlockSize() - 11).
(emphasis mine)
You're using PKCS1 padding. So if the block size is 256, you can only encrypt up to 245 bytes at a time.
I need to hand assemble 14bit MIDI Pitch Bend values from raw UInt16 values in iOS. I'm wondering if anybody out there has had a chance to come up with an elegant solution? Here's where I'm at - I'll get a chance to test this probably later today, but if I hear back before then, great:
First, some MIDI preliminaries for anybody curious.
MIDI Pitch Bend is broken up into one Status Byte followed by two Data Bytes (it's a 14bit controller), these two Data Bytes are associated with their Status Byte by both leading with a Zero status bit, MIDI Spec has them appearing in the order of MSB -> LSB
(Edit: Update, it's actually Status -> LSB -> MSB )
( ie 1110 0000, 0111 1111, 0111 1111 )
The challenge is how to break up an ARM/Intel 16bit UInt16 into two 7 bit segments on iOS, and have it make sense for MIDI?
Please keep in mind that, because we're dealing with an unsigned integer, a 0 value is NOT neutral pitch bend, but rather full pitch down - where as neutral pitch bend is defined as 8192 - and 16,383 is full pitch up.
So here's my best guess as to how to do this:
UInt16 msbAnd = base10ValueUInt16 & 16256; //clearing out LSB
UInt16 msbAndShift = msbAnd << 1; //shift into leading Byte, with 0 status bit
UInt16 lsbAnd = base10ValueUInt16 & 127; //isolating LSB
UInt16 finalTwoBytePitchWord = msbFinalAndShift | lsbAnd; //make UInt16 word
UInt16 finalTwoBytePitchWordFlipped = CFSwapInt16HostToBig(finalTwoBytePitchWord); //Endian tweak
This code runs fine and seems to create the two Data Bytes with the required zero status bits and flips them around from little endian Intel/ARM which seems to be necessary for MIDI (MIDI is STATUS -> MSB -> LSB ): I can slap on the leading Status Byte with the appropriate MIDI channel later.
So, does this make sense? Has anybody come up with a more elegant solution? ( is there a Library I'm overlooking? ) ... I'll check back in later and also let folks know if this actually worked on the sampler I have to target it at.
Thanks
I think your code is close to right, but it's overly complicated. This question has nothing to do with iOS or endianness or ARM or Intel; it's just plain old C bit-twiddling. If you write the code correctly, it will work on any reasonable platform without modification. You don't need a library; it's only a couple lines of code.
It's best to work with MIDI on a byte-by-byte basis. You want a function that takes a 16-bit unsigned integer (which we'll trust has at most 14 bits worth of value) and returns two single-byte values, one with the most significant bits, one with the least significant bits.
Later on, when you send the message, you assemble the bytes in the appropriate order. According to the specification, pitch wheel messages are three bytes: STATUS, then LSB, then MSB. You have them backwards in your question!
The least-significant 7 bits are easy: just mask off those bits from the original value. The most-significant 7 bits are similar: mask off the next higher 7 bits from the original value, then shift them down.
It doesn't matter whether the 16-bit integers are little-endian or big-endian in memory on your machine; the compiler takes care of that.
Here's a function and a test tool.
#include <stdio.h>
#include <stdint.h> // for C standard uint8_t and uint16_t
// or, if you prefer, use unsigned char and unsigned short, or Byte and UInt16;
// they'll all work, although some are more portable than others
void encode14BitValue(uint16_t value, uint8_t *out_msb, uint8_t *out_lsb)
{
uint16_t mask = 0x007F; // low 7 bits on
// "(1 << 7) - 1" is arguably clearer
*out_lsb = value & mask;
*out_msb = (value & (mask << 7)) >> 7;
}
int main(int argc, const char * argv[])
{
typedef struct {
uint16_t in;
uint8_t expected_msb;
uint8_t expected_lsb;
} test_case;
test_case cases[] = {
{ 0x0000, 0x00, 0x00 },
{ 0x0001, 0x00, 0x01 },
{ 0x0002, 0x00, 0x02 },
{ 0x0004, 0x00, 0x04 },
{ 0x0008, 0x00, 0x08 },
{ 0x0009, 0x00, 0x09 },
{ 0x000F, 0x00, 0x0F },
{ 0x0010, 0x00, 0x10 },
{ 0x0011, 0x00, 0x11 },
{ 0x001F, 0x00, 0x1F },
{ 0x0020, 0x00, 0x20 },
{ 0x0040, 0x00, 0x40 },
{ 0x0070, 0x00, 0x70 },
{ 0x007F, 0x00, 0x7F },
{ 0x0080, 0x01, 0x00 },
{ 0x0081, 0x01, 0x01 },
{ 0x008F, 0x01, 0x0F },
{ 0x0090, 0x01, 0x10 },
{ 0x00FF, 0x01, 0x7F },
{ 0x0100, 0x02, 0x00 },
{ 0x0200, 0x04, 0x00 },
{ 0x0400, 0x08, 0x00 },
{ 0x0800, 0x10, 0x00 },
{ 0x1000, 0x20, 0x00 },
{ 0x1FFF, 0x3F, 0x7F },
{ 0x2000, 0x40, 0x00 },
{ 0x2001, 0x40, 0x01 },
{ 0x3FFF, 0x7F, 0x7F },
};
int passed = 1;
for (int i = 0, c = sizeof(cases) / sizeof(cases[0]); i < c; i++) {
uint8_t msb, lsb;
encode14BitValue(cases[i].in, &msb, &lsb);
if (cases[i].expected_msb != msb || cases[i].expected_lsb != lsb) {
printf("failed: 0x%04hX expected 0x%02hhX 0x%02hhX got 0x%02hhX 0x%02hhX\n", cases[i].in, cases[i].expected_msb, cases[i].expected_lsb, msb, lsb);
passed = 0;
}
}
return passed ? 0 : 1;
}
In your code, trying to pack the two bytes of result into one 16-bit integer just adds confusion. I don't know why you're doing that, since you're going to have to extract individual bytes again, whenever you send the MIDI anywhere else. That's where any worries about endianness come up, since your packing and unpacking code have to agree. You might as well not bother. I bet your code was incorrect, but your error in swapping MSB and LSB compensated for it.