populate array with nsmutabledata swift - ios

How can i populate an array with nsmutabledata in swift?
Heres my code :
func hashTest(hash:[UInt8]) {
var arrayOfBytes = NSMutableData()
for var i = 0; i < hash.count; i++ {
if i < 21 {
arrayOfBytes.appendBytes(hash[i] as UInt8, length: 1)
}
}
}
But i get the following error :
Cannot invoke initializer for type 'UnsafePointer<UInt8>' with an argument list of type '(UInt8)'
Im trying to repeat something like this :
let endMarker = NSData(bytes: [0xa1, 0x11, 0xa9, 0xf5, 0xce, 0xdb, 0x18, 0xfb, 0xed, 0xd7, 0x67, 0x25, 0x86, 0xe7, 0xd6, 0x42, 0x96, 0x0f, 0x95, 0xe8] as [UInt8], length: 20)

Just put & in front of hash[i] , that will allow for the unsafe pointer to go into append bytes
func hashTest(var hash:[UInt8]) {
var arrayOfBytes = NSMutableData()
for var i = 0; i < hash.count; i++ {
if i < 21 {
arrayOfBytes.appendBytes(&hash[i], length: 1)
}
}
}

Related

Convert ECPublicKey(SecKey) to PEM String in swift

I want to convert ECPublicKey to PEM format as below
"-----BEGIN PUBLIC
KEY-----MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEo0WcFrFClvBE8iZ1Gdlj+mTgZoJWMNE3kDKTfRny2iaguwuSYxo+jCnXqzkR+kyFK9CR3D+pypD1sGb1BnfWAA==-----END
PUBLIC KEY-----"
Generated ECPublicKey with key Type "ECC/ECDSA/spec256r1". Below is the print
<SecKeyRef curve type: kSecECCurveSecp256r1, algorithm id: 3, key
type: ECPublicKey, version: 4, block size: 256 bits, y:
B6EEBB3791933312E10BD7C3D65C950AB7E1C325BCDB57A8663EB7B1E29BFA77, x:
1D41FDAD2137316D415B117227BCC465566E56A54E7B2B9B3A4B66C15A067611,
addr: 0x7f818850f6d0>
To my knowledge PEM format is nothing but base64 encoded string along with header and footer. Tried below code, but no success
var error:Unmanaged<CFError>?
guard let cfdata = SecKeyCopyExternalRepresentation(publicKey, &error)
else { return }
let data:Data = cfdata as Data
let b64String = data.base64EncodedString()
Appreciate any help here
Start by converting to ASN.1 format:
(see your decoded example in ASN.1 Decoder)
let publicKeyData: CFData = ...
let ecHeader: [UInt8] = [
/* sequence */ 0x30, 0x59,
/* |-> sequence */ 0x30, 0x13,
/* |---> ecPublicKey */ 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01, // (ANSI X9.62 public key type)
/* |---> prime256v1 */ 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, // (ANSI X9.62 named elliptic curve)
/* |-> bit headers */ 0x07, 0x03, 0x42, 0x00
]
var asn1 = Data()
asn1.append(Data(ecHeader))
asn1.append(publicKeyData as Data)
Then Base64-encode and add PEM header & footer:
let encoded = asn1.base64EncodedString(options: .lineLength64Characters)
let pemString = "-----BEGIN PUBLIC KEY-----\r\n\(encoded)\r\n-----END PUBLIC KEY-----\r\n"

convert list of hex string to hex list

I would need to convert this list of Strings:
[00, 02, F0, 12, 04, 00, 00, 05, 03, 01]
into
[0x00, 0x02, 0xF0, 0x12, 0x04, 0x00, 0x00, 0x05, 0x03, 0x01]
How can I achieve this?
This function may help you:
toHex() method can convert unit8stringlist to hex list
toUnitList() method can convert hex list to unit8stringlist
static toHex(Uint8List bArr) {
int length;
if (bArr == null || (length = bArr.length) <= 0) {
return "";
}
Uint8List cArr = new Uint8List(length << 1);
int i = 0;
for (int i2 = 0; i2 < length; i2++) {
int i3 = i + 1;
var cArr2 = [
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'
];
var index = (bArr[i2] >> 4) & 15;
cArr[i] = cArr2[index].codeUnitAt(0);
i = i3 + 1;
cArr[i3] = cArr2[bArr[i2] & 15].codeUnitAt(0);
}
return new String.fromCharCodes(cArr);
}
static hex(int c) {
if (c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0)) {
return c - '0'.codeUnitAt(0);
}
if (c >= 'A'.codeUnitAt(0) && c <= 'F'.codeUnitAt(0)) {
return (c - 'A'.codeUnitAt(0)) + 10;
}
}
static toUnitList(String str) {
int length = str.length;
if (length % 2 != 0) {
str = "0" + str;
length++;
}
List<int> s = str.toUpperCase().codeUnits;
Uint8List bArr = Uint8List(length >> 1);
for (int i = 0; i < length; i += 2) {
bArr[i >> 1] = ((hex(s[i]) << 4) | hex(s[i + 1]));
}
return bArr;
}
I am confused about what you really want but here is an example of some operations you can do:
void main() {
// List of strings
final input = ['00', '02', 'F0', '12', '04', '00', '00', '05', '03', '01'];
// List of ints
final output = input.map((e) => int.parse(e, radix: 16)).toList();
// Print list of ints in radix 10
print(output); // [0, 2, 240, 18, 4, 0, 0, 5, 3, 1]
// Print list of ints as hex strings
print(output.map(toHexString).toList());
// [0x00, 0x02, 0xf0, 0x12, 0x04, 0x00, 0x00, 0x05, 0x03, 0x01]
}
String toHexString(int number) =>
'0x${number.toRadixString(16).padLeft(2, '0')}';
And if your strings are actually beginning with "0x" you can do this:
void main() {
// List of strings
final input = ['0x00', '0x02', '0xF0', '0x12', '0x04', '0x00', '0x00', '0x05', '0x03', '0x01'];
// List of ints
final output = input.map((e) => int.parse(e.replaceFirst('0x', ''), radix: 16)).toList();
// Print list of ints in radix 10
print(output); // [0, 2, 240, 18, 4, 0, 0, 5, 3, 1]
// Print list of ints as hex strings
print(output.map(toHexString).toList());
// [0x00, 0x02, 0xf0, 0x12, 0x04, 0x00, 0x00, 0x05, 0x03, 0x01]
}
String toHexString(int number) =>
'0x${number.toRadixString(16).padLeft(2, '0')}';

SHA256 Swift to Objective C equivalence

Hello everyone I'm working for the first time with SHA256 and I'm trying to follow a tutorial on this my problem is to write the equivalence in Objective C of SHA 256. I'm trying to understand the function that I show you below but I still have problems on how to find the equivalence in Objective C of this Swift function
let rsa2048Asn1Header:[UInt8] = [
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00
]
private func sha256(data : Data) -> String {
var keyWithHeader = Data(bytes: rsa2048Asn1Header)
keyWithHeader.append(data)
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
keyWithHeader.withUnsafeBytes {
_ = CC_SHA256($0, CC_LONG(keyWithHeader.count), &hash)
}
return Data(hash).base64EncodedString()
}
Can you help me ?
Working with raw bytes in Objective-C is generally a little more straightforward than Swift. An implementation like this should be equivalent.
#define RSA_2048_ASN1_HDR_LEN 24
- (NSString *)sha256:(NSData *)data {
NSMutableData *keyWithHeader = [NSMutableData dataWithBytes:rsa2048Asn1Header length:RSA_2048_ASN1_HDR_LEN];
[keyWithHeader appendData:data];
UInt8 hash[CC_SHA256_DIGEST_LENGTH] = { 0 };
CC_SHA256(keyWithHeader.bytes, (CC_LONG) keyWithHeader.length, hash);
return [[NSData dataWithBytes:hash length:CC_SHA256_DIGEST_LENGTH] base64EncodedStringWithOptions:0];
}
Note that you'll also need to import the common crypto library into your Objective-C file as well:
#import <CommonCrypto/CommonDigest.h>

How to store and retrieve byte array [UInt8] into sqlite3 database using BLOB in swift?

let arr: [UInt8] = [0x14, 0x00, 0xAB, 0x45, 0x49, 0x1F, 0xEF, 0x15, 0xA8, 0x89, 0x78, 0x0F, 0x09, 0xA9, 0x07, 0xB0, 0x01, 0x20, 0x01, 0x4E, 0x38, 0x32, 0x35, 0x56, 0x20, 0x20, 0x20, 0x00]
How can i store in sqlite3 or in NSUserDefaults
i have tried like this
let arrData = NSData(bytes: &arr, length: (arr?.count)!)
let d = NSUserDefaults.standardUserDefaults()
d.setObject(arrData, forKey: "mydata")
d.synchronize()
let obj = d.objectForKey("mydata")
let objData = obj as! NSData
let resultArr = NSKeyedUnarchiver.unarchiveObjectWithData(objData) as! [UInt8]
print(resultArr.count)
For NSUserDefaults:
let integersToStore: [UInt8] = [0x14, 0x00, 0xAB, 0x45, 0x49, 0x1F, 0xEF, 0x15, 0xA8, 0x89, 0x78, 0x0F, 0x09, 0xA9, 0x07, 0xB0, 0x01, 0x20, 0x01, 0x4E, 0x38, 0x32, 0x35, 0x56, 0x20, 0x20, 0x20, 0x00]
let dataToStore = NSData(bytes: integersToStore, length: integersToStore.count)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(dataToStore, forKey: "mydata")
defaults.synchronize()
// get the data we stored in NSUserDefaults
if let readData = defaults.dataForKey("mydata") {
// determine the number of UInt8 to read from this data
let count = readData.length / sizeof(UInt8)
// create a new UInt8 array with the correct count
var readArray = [UInt8](count: count, repeatedValue: 0)
// copy data into array
readData.getBytes(&readArray, length: count * sizeof(UInt8))
// readArray has what you need
print(readArray)
}
Note: Don't expect the correct result when testing this in a playground.

IOS App to decode a frame and display using AVSampleBufferDisplayLayer fails

I am writing a IOS App which will decode a H.264 frame and render using AVSampleBufferDisplayLayer. I have already modified the frame to not have the NAL start code but have a 4 byte NAL size. This has been verified.
But all i see is a white frame in my IOS simulator, No error; is there a possibility to dump the decoded frame and verify? Any other debug points will really help.
#implementation DecodeClass
- (void) viewDidLoad {
}
/* method to decode and render a frame */
- (void)decodeFrame{
NSLog(#"Decode Start");
/* local variable declaration */
//OSStatus status;
size_t spsSize, ppsSize,dataLen;
//_frameSize = 320*240*1.5;
uint8_t sps[] = {0x67, 0x42, 0xC0, 0x0D, 0x96, 0x64, 0x0A, 0x0F, 0xDF, 0xF8, 0x00, 0x20, 0x00, 0x18, 0x80, 0x00,
0x00, 0x7D, 0x00, 0x00, 0x0B, 0xB5, 0x47, 0x8A, 0x15, 0x50};
uint8_t pps[] = {0x68, 0xCE, 0x32, 0xC8};
const uint8_t* props[] = {sps, pps};
spsSize = (sizeof(sps)/sizeof(uint8_t));
ppsSize = (sizeof(pps)/sizeof(uint8_t));
const size_t sizes[] = {spsSize,ppsSize};
FILE* pFile;
int result;
pFile = fopen("/Documents/input_mod1.264","r");
fseeko(pFile, 0, SEEK_END);
unsigned long fileSize = ftello(pFile);
fseek(pFile, 0, SEEK_SET);
_dataBuf = (uint8_t*)malloc(sizeof(uint8_t) * (fileSize));
memset(_dataBuf,0,sizeof(uint8_t) * (fileSize));
if (pFile ){
result = fread(_dataBuf,sizeof(uint8_t),fileSize,pFile);
fclose(pFile);
}
else
NSLog(#"Can't open file");
[self MUX_Modify_AVC_Start_Code:_dataBuf size:&fileSize Header:false];
dataLen = fileSize;
//construct h.264 parameter set
CMVideoFormatDescriptionRef formatDesc;
OSStatus formatCreateResult = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault, 2, props, sizes, 4, &formatDesc);
if (formatCreateResult)
{
NSLog(#"construct CMVideoFormatDescriptionCreateFromH264ParameterSets Failed :%ld",(long)formatCreateResult);
}
//construct cmBlockbuffer .
CMBlockBufferRef blockBufferOut = nil;
CMBlockBufferCreateEmpty (0,0,kCMBlockBufferAlwaysCopyDataFlag, &blockBufferOut);
CMBlockBufferAppendMemoryBlock(blockBufferOut,
_dataBuf,
dataLen,
NULL,
NULL,
0,
dataLen,
kCMBlockBufferAlwaysCopyDataFlag);
//construct cmsamplebuffer ok
size_t sampleSizeArray[1] = {0};
sampleSizeArray[0] = CMBlockBufferGetDataLength(blockBufferOut);
CMSampleTimingInfo tmInfos[1] = {
{CMTimeMake(5,1), CMTimeMake(5,1), CMTimeMake(5,1)}
};
CMSampleBufferRef sampBuf = nil;
formatCreateResult = CMSampleBufferCreate(kCFAllocatorDefault,
blockBufferOut,
YES,
NULL,
NULL,
formatDesc,
1,
1,
tmInfos,
1,
sampleSizeArray,
&sampBuf);
NSLog(#"Decode End :: Construct CMSampleBufferRef value of formatCreateResult is %d", formatCreateResult);
if(!_dspLayer)
{
_dspLayer = [[AVSampleBufferDisplayLayer alloc]init];
[_dspLayer setFrame:CGRectMake(0,0,320,240)];
_dspLayer.bounds = CGRectMake(0, 0, 300, 300);
_dspLayer.videoGravity = AVLayerVideoGravityResizeAspect;
_dspLayer.position = CGPointMake(500, 500);
_dspLayer.backgroundColor = [UIColor blueColor].CGColor;
CMTimebaseRef tmBase = nil;
CMTimebaseCreateWithMasterClock(NULL,CMClockGetHostTimeClock(),&tmBase);
_dspLayer.controlTimebase = tmBase;
CMTimebaseSetTime(_dspLayer.controlTimebase, kCMTimeZero);
CMTimebaseSetRate(_dspLayer.controlTimebase, 1.0);
[self.layerView.layer addSublayer:_dspLayer];
}
//put to AVSampleBufferdisplayLayer,just one frame.
if([self.dspLayer isReadyForMoreMediaData])
{
[self.dspLayer enqueueSampleBuffer:sampBuf];
}
[self.dspLayer setNeedsDisplay];
}
-(void)MUX_Modify_AVC_Start_Code:(uint8_t*)pData size:(uint32_t *)nSize Header:(bool)bHeader{
....
}
-(uint32_t)MUX_FindNextPattern:(uint8_t*)streamBuf buffSize:(uint32_t)bufSize startCode:(uint32_t)startcode{
....
}
- (void)dealloc{
//free(_dataBuf);
}
#end
int main(int argc, char * argv[]) {
//[decodeClass release];
#autoreleasepool {
DecodeClass *decodeClass = [[DecodeClass alloc]init];
[decodeClass decodeFrame];
decodeClass = nil;
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

Resources