#APNS for #IOS13 in C#

1_yVRIJRb4z-F3ahDKsMVcpw

APNS, or apple’s push notification service has changed a bit in iOS 13, so you need to make some changes to your code to make it work again.

First off, I used to use MOON APNS (https://github.com/arashnorouzi/Moon-APNS/issues) but it seems to be no longer maintained. It used a raw TCP/IP mechanism, which I’m sure is ultra-performant, but it’s really hard to debug, so I decided to just change the framework to PushSharp (https://github.com/Redth/PushSharp)

Now, my code is very much a fire and forget, if it works, good, it it doesn’t – nevermind. I’m not catching or logging any exceptions, you might want to do this. I’m not getting into how to create the .P12 key, that’s a whole post on it’s own.

public static void Push(string message, string apns)
{
// Change p12 after acceptance!
var strP12 = HttpContext.Current.Server.MapPath(“~/certs/2020/sandbox.2020.p12”);
var config = new ApnsConfiguration (ApnsConfiguration.ApnsServerEnvironment.Sandbox,
strP12, “xxxxxx”);
var apnsBroker = new ApnsServiceBroker (config);
apnsBroker.Start ();
apnsBroker.OnNotificationSucceeded += (notification) =>
{
apnsBroker.Stop();
};
var oPayload = new
{
aps = new
{
alert = new
{
body = message
}
}
};
var payloadJson = JsonConvert.SerializeObject(oPayload);
apnsBroker.QueueNotification (new ApnsNotification {
DeviceToken = apns,
Payload = JObject.Parse(payloadJson)
});
}

It only sends a text message, it doesn’t have badges, sounds, or alerts, but that’s all I needed.

 

 

Categories: Uncategorized

How to duplicate a #partition in Windows using Disk Managment

resynching

If you want to duplicate a partition, to create an exact copy of it, then there are probably plenty of tools to do this. However, you can also do it with Disk Management – Which is available under the Computer Management tool in Windows.

First thing, is to click on the partition you want to copy, and select “Add mirror”, then select the empty partition you want to copy the data on to.

This process will take several hours, and will only show progress after 30 minutes or so – Depending on the speed of your system.

Once complete, right click on the partition, and select “Break Mirrored Volume”, you will now have two identical drives.

break-mirror

 

 

 

Categories: Uncategorized

Automatically translate #Udemy captions using #Microsoft #Azure #Cognitive services.

captions editor

Udemy has a great system for captioning videos, but perhaps you want to appeal to an international audience, and include captions in multiple languages. The best solution, of course it is to have them professionally translated, but if you want a cheap solution (and poor-quality), then you can run them through an automated translator like Azure cognitive services.

The code here is in C#, and is available on Github here; https://github.com/infiniteloopltd/vtt-translate

You download the VTT file (which is a bit like an SRT), and run it through this code;

private static string FromString(string english, string to)
{
const string host = “https://api.cognitive.microsofttranslator.com”;
var route = “/translate?api-version=3.0&from=en&to=” + to;
var subscriptionKey = ConfigurationManager.AppSettings[“subscription”];
var body = new object[] { new { Text = english } };
var requestBody = JsonConvert.SerializeObject(body);
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(host + route);
request.Content = new StringContent(requestBody, Encoding.UTF8, “application/json”);
request.Headers.Add(“Ocp-Apim-Subscription-Key”, subscriptionKey);
var response = client.SendAsync(request).Result;
var jsonResponse = response.Content.ReadAsStringAsync().Result;
var jResponse = JArray.Parse(jsonResponse);
foreach (var translation in jResponse[0][“translations”])
{
var strText = translation[“text”].ToString();
return strText;
}
}
return null;
}

Obviously, you’ll need your own subscription key from azure, but the free tier covers 2M chars.

Categories: Uncategorized

Techies can help reduce the spread of the #CoronaVirus too.

covid19-cdc-unsplash

I’d like to put forward an idea, that techies can help in the effort to limit the spread of the virus.
Many people still need to go to offices during lockdown, if their job is necessary. But, perhaps some of these people *could* work from home if they had the right IT systems in place to allow them to do so.
If you know of someone who still has to go to an office to work, and perhaps their job could potentially be done from home – but maybe their office doesn’t have secure access to office files remotely (i.e. a VPN?), or perhaps the phone line can’t be forwarded to another location (SIP Forwarding ? )
Let’s try and free up workers who need to do their job, but not necessarily from an office! – Feel free to tag anyone, and we can put our heads together to find a solution.
Categories: Uncategorized

Improving ML.NET accuracy by connecting 2 neural networks #AI #ML

A-system-of-two-neural-networks-The-output-layer-of-the-first-neural-network-provides

In this case, I am using the Issue Classification scenario in ML.NET, where I initially trained a network to predict an output on 24 inputs. The result was a very poor 10%, but I had an idea, to create a second training set, based on the inital inputs, plus the outputs (The SCORE array) of the network (31 elements).

By creating a new table, with the initial 24 inputs, the training output, and the  scrore array, i.e. another 31 floats, I then created a table that was 56 columns wide, and I used that again to train on ML.NET.

Using this second-level neural network, I effectively created a neural network with twice the number of layers, and the accuracy went from 10% to 30%.

I am hoping to repeat this process another number of times to gradually increase the accuracy up to a usable level of 90%.

No code examples yet; but if the repeated process actually increases this right up to 90%+, then I’ll share!

 

Categories: Uncategorized

Dealing with #Overfitting in ML.NET (#AI / #ML)

confidence

One of the issues with ML.NET, is that it will tend to be over-eager to provide a prediction, even when there is not enough information to go on, in order to make any sort of accurate prediction. This is where you should also look at the Score Property, and take the Max Value of this array in order to determine the level of confidence.

If you then plot confidence against correct predictions and incorrect predictions, and hopefully you should see that incorrect predictions should lie primarily on the lower end of the confidence scale, and correct predictions should lie on the higher end of the confidence scale.

Ideally, you should see a clearer delimination between correct and incorrect, to allow you say that if confidence is less than .3 (or whatever), then the prediction is unknown, not the wild guess that ML.NET has suggested.

To generate this graph, here is the SQL I used;

create table PercentileGraph
(
id int identity(0,1),
[Start] as cast(id as float)/100,
[End] as cast(id as float)/100 + 0.01,
Correct int,
Incorrect int,
)

while 1=1
begin
insert into PercentileGraph default values
end

— Run for a second, then stop

delete from PercentileGraph where id>100

select * from PercentileGraph

update PercentileGraph set correct =
(
select count(*) from Evaluation where
Model=Predicted
and ModelConfidence>=PercentileGraph.[start]
and ModelConfidence<=PercentileGraph.[end]
)

update PercentileGraph set incorrect =
(
select count(*) from Evaluation where
Model<>Predicted
and ModelConfidence>=PercentileGraph.[start]
and ModelConfidence<=PercentileGraph.[end]
)

select * from PercentileGraph

Categories: Uncategorized

#DES Encryption using #BouncyCastle in C#

DES-BOUNCYCASTLE

DES or the Data Encryption Standard, is a classic symetric encryption algorithm that is largely been superceeded by AES and 3DES nowadays, but you may have a legacy format that still uses DES, so you will need to interoperate with it.

This code example uses the BouncyCastle library in C# to perform DES encryption and decryption with an 8 byte (64 bit) key, and is available here; https://github.com/infiniteloopltd/DES

It is a 8 byte block cypher, like Blowfish, so your ciphertext will be bloated by a maximum of 8 bytes – So it’s economicical with memory on short plaintexts.

I’ve used byte arrays here as inputs and outputs for flexibility;

private static byte[] DES_Encrypt(byte[] input, byte[] key)
{
var engine = new DesEngine();
var cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine));
cipher.Init(true, new KeyParameter(key));
var cipherText = new byte[cipher.GetOutputSize(input.Length)];
var outputLen = cipher.ProcessBytes(input, 0, input.Length, cipherText, 0);
cipher.DoFinal(cipherText, outputLen);
return cipherText;
}

And the decyption is as follows;

private static byte[] DES_Decrypt(byte[] key, byte[] cipherText)
{
var engine = new DesEngine();
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine));
cipher.Init(false, new KeyParameter(key));
var plainText = new byte[cipher.GetOutputSize(cipherText.Length)];
var outputLen = cipher.ProcessBytes(cipherText, 0, cipherText.Length, plainText, 0);
cipher.DoFinal(plainText, outputLen);
return plainText;
}

 

Categories: Uncategorized

“Hello World” in #GeneticAlgorithms in C#

maxresdefault

Genetic algoritms are a computational representation of what happens in nature, how evolution solves problems, so it applies a “survival of the fittest” approach to solving a problem.

Like Machine Learning, instead of prescribing the solution to a problem you provide problem examples and corresponding solutions, and let the GA (Genetic Algorithm) try to figure out how to solve that problem.

Like in nature, (If we ignore religion for a moment!), nobody designed a cheetah to run faster than a gazelle, but when presented with a problem of a fast gazelle, the solution was to run faster than it. Other solutions, like running backwards, were not effective, and so were not selected for.

So, TL;DR; here is the github repo, which as code in C# using GeneticSharp to solve a very simple problem; https://github.com/infiniteloopltd/geneticAlgorithm_helloWorld

Here, the problem posed is simple addition;

// 1 + 1 = 2
// 2 + 2 = 4
// 3 + 2 = 5

However, you can substitute the parameters with more complex equations, and the GA will still try to solve it, it just will take longer.

The “Genes” of the GA are addition, substration, multiplation, division, and constant numbers (1,2,3). So, it will probably struggle to solve Sin(), Tan(), Cos() etc. Like in the same way that DNA is limited to making protiens, so you can’t make Petrol using DNA.

So, to wrap up this post, here is the code to run a simple equation solver using Genetic Algorithms;

static void Main(string[] args)
{
// Problem: Simple addition
// 1 + 1 = 2
// 2 + 2 = 4
// 3 + 2 = 5
var myInputs = new List<FunctionBuilderInput>
{
new FunctionBuilderInput(new List<double> {1, 1}, 2),
new FunctionBuilderInput(new List<double> {2, 2}, 4),
new FunctionBuilderInput(new List<double> {3, 2}, 5)
};
var myFitness = new FunctionBuilderFitness(myInputs.ToArray());
var myChromosome = new FunctionBuilderChromosome(myFitness.AvailableOperations, 5);
var selection = new EliteSelection();
var crossover = new ThreeParentCrossover();
var mutation = new UniformMutation(true);
var fitness = myFitness;
var chromosome = myChromosome;
var population = new Population(100, 200, chromosome)
{
GenerationStrategy = new PerformanceGenerationStrategy()
};
var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation)
{
Termination = new FitnessThresholdTermination(0)
};
ga.GenerationRan += delegate
{
Console.Clear();
var bestChromosome = ga.Population.BestChromosome;
Console.WriteLine(“Generations: {0}”, ga.Population.GenerationsNumber);
Console.WriteLine(“Fitness: {0,10}”, bestChromosome.Fitness);
Console.WriteLine(“Time: {0}”, ga.TimeEvolving);
Console.WriteLine(“Speed (gen/sec): {0:0.0000}”, ga.Population.GenerationsNumber / ga.TimeEvolving.TotalSeconds);
var best = bestChromosome as FunctionBuilderChromosome;
Console.WriteLine(“Function: {0}”, best.BuildFunction());
};
ga.Start();
Console.WriteLine(“Evolved.”);
Console.ReadKey();
}

 

Categories: Uncategorized

Cryptanalysis with #ML.NET (#AI / #ML)

1200px-Mldotnet.svg

Disclaimer: This approach works only when you have a limited-length plaintext, and plenty (millions) of examples of cyphertext / plaintext pairs. I achieved 90%+  accuracy with this approach, it’s not perfect, and requires several days of training (8 hours per character of plaintext)

So, imagine you have a database held in SQL server that holds a list of cyphertext and corresponding plaintext examples – even if you don’t even know the cypher used, you can still use ML.NET as a means of Cryptanalysis. Without knowing the cypher used, you can’t use brute-force as an approach.

What I did – I broke the cyphertext into individual columns – So one column represented one character of the cyphertext, and I did the same with the plaintext, breaking up the plaintext into one column per character.

Then I ran a classification model for 8 hours on 1 million rows of examples, using the ML.NET model builder, providing each column of the cyphertext as the input, and one column at a time of the plaintext as the label (output).

After 8 days, I had 8 different ML.NET models that could decode the cyphertext.

WITHOUT – even knowing what cypher was being used.

RESULT

Categories: Uncategorized

Restoring a cancelled ML.NET trained network #AI #MachineLearning #ML.NET

cancelled

If you’re using the ML.NET VS Add-in to train your models, you may find it really frustrating if the training suddenly cancels itself, or you accidentally cancel it, and if you’re doing an 8 hour train, then this can drive you nuts.

Thankfully, I found the temporary files, that it generates, and you can still use in your code, although it generates about 10 different models per algorithm, so you’ll need to experiment to find the one that works best (typically it’ll be the 9th or 10th)

So, where are the files?

<user>\AppData\Local\Temp\Microsoft.ML.AutoML

Phew!

And how to load them in?, here’s some sample code;

private static ModelOutput Predict(ModelInput input)
{

if (predictionEngine == null)
{
// Create new MLContext
MLContext mlContext = new MLContext();

ITransformer mlModel = mlContext.Model.Load(modelPath, out var modelInputSchema);
predictionEngine = mlContext.Model.CreatePredictionEngine<ModelInput, ModelOutput>(mlModel);
}

// Use model to make prediction on input data
var result = predictionEngine.Predict(input);
return result;
}

Where you statically define the following variables;

private static PredictionEngine<ModelInput, ModelOutput> predictionEngine = null;

private static string modelPath = @””;

modelpath being the ZIP file of the model.

 

 

Categories: Uncategorized