How to Solve the Traveling Salesman Problem in Kotlin

The traveling salesman problem (TSP) is a classic optimization problem that asks: given a list of cities and the distances between each pair of cities, what is the shortest possible route that visits each city exactly once and returns to the origin city?1

This problem is NP-hard, which means that there is no known polynomial-time algorithm to find the optimal solution. However, there are many heuristics and exact algorithms that can solve the problem for small or medium-sized instances, or approximate the solution for large instances.

In this blog post, we will explore some of these methods and how to implement them in Kotlin, a modern and concise programming language that is widely used by Android developers and interoperable with Java.23

Brute Force

The simplest way to solve the TSP is to generate all possible permutations of the cities and calculate the cost of each one. Then, we can return the permutation with the minimum cost as the optimal solution.

This method is guaranteed to find the optimal solution, but it is very inefficient. The number of permutations grows factorially with the number of cities, so for n cities, there are n! possible routes. For example, if we have 10 cities, there are 10! = 3,628,800 possible routes. If we have 20 cities, there are 20! = 2.43 x 10^18 possible routes.

To implement this method in Kotlin, we can use a vector to store all the cities except the starting city. Then, we can use the nextPermutation function from the Kotlin standard library to generate all possible permutations of this vector. For each permutation, we can calculate the cost by adding up the distances between consecutive cities and between the last city and the starting city. We can keep track of the minimum cost and the corresponding permutation using two variables. Finally, we can return the permutation with the minimum cost as the optimal solution.

Here is an example of how this method looks like in code:

// A function that calculates the cost of a route fun calculateCost(graph: Array<IntArray>, route: List<Int>, start: Int): Int { var cost = 0 var current = start for (city in route) { cost += graph[current][city] current = city } cost += graph[current][start] return cost } // A function that solves the TSP using brute force fun solveTSPBruteForce(graph: Array<IntArray>, start: Int): List<Int> { // Create a vector of all cities except the start val cities = mutableListOf<Int>() for (i in graph.indices) { if (i != start) { cities.add(i) } } // Initialize the minimum cost and the optimal route var minCost = Int.MAX_VALUE var optimalRoute = listOf<Int>() // Generate all permutations of cities do { // Calculate the cost of the current permutation val cost = calculateCost(graph, cities, start) // Update the minimum cost and the optimal route if needed if (cost < minCost) { minCost = cost optimalRoute = cities.toList() } } while (cities.nextPermutation()) // Return the optimal route return optimalRoute }

Nearest Neighbor

A more efficient way to solve the TSP is to use a heuristic that builds a route by choosing the nearest city at each step. This method is not guaranteed to find the optimal solution, but it is much faster than brute force.

The idea is to start from any city and mark it as visited. Then, find the nearest unvisited city and move to it. Repeat this process until all cities are visited. Finally, return to the starting city to complete the route.

This method has a time complexity of O(n^2), where n is the number of cities. This is because we need to loop through all cities and find the nearest unvisited city at each step.

To implement this method in Kotlin, we can use a boolean array to keep track of which cities are visited. Then, we can use a loop to iterate through all cities and find the nearest unvisited city using a nested loop. We can add each city to a list as we visit them. Finally, we can return the list as the solution.

Here is an example of how this method looks like in code:

// A function that solves the TSP using nearest neighbor heuristic fun solveTSPNearestNeighbor(graph: Array<IntArray>, start: Int): List<Int> { // Create an array of visited cities val visited = BooleanArray(graph.size) { false } // Mark the start city as visited visited[start] = true // Create a list to store the route val route = mutableListOf<Int>() // Add the start city to the route route.add(start) // Initialize the current city as start var current = start // Loop until all cities are visited while (route.size < graph.size) { // Initialize the minimum distance and the nearest city var minDistance = Int.MAX_VALUE var nearestCity = -1 // Loop through all cities for (i in graph.indices) { // Skip if the city is visited or same as current if (visited[i] || i == current) continue // Update the minimum distance and nearest city if needed if (graph[current][i] < minDistance) { minDistance = graph[current][i] nearestCity = i } } // Mark the nearest city as visited visited[nearestCity] = true // Add it to the route route.add(nearestCity) // Update current city as nearest city current = nearestCity } // Return route return route }

Dynamic Programming

A more advanced way to solve the TSP is to use a dynamic programming algorithm that exploits the overlapping subproblems and optimal substructure of the problem. This method can find the optimal solution in polynomial time, but it requires a lot of memory.

The idea is to use a two-dimensional array to store the minimum cost of visiting a subset of cities and ending at a specific city. The array is indexed by a bitmask that represents the subset of cities and an integer that represents the last city. The base case is when the subset contains only one city, which is the starting city. The cost is zero in this case. The recursive case is when the subset contains more than one city. The cost is the minimum of the cost of visiting the previous subset and ending at any other city plus the distance from that city to the current city.

This method has a time complexity of O(n^2 * 2^n), where n is the number of cities. This is because we need to fill up the array for all possible subsets of cities and all possible last cities. The array has a size of 2^n * n.

To implement this method in Kotlin, we can use a nested function that takes a bitmask and a last city as parameters and returns the minimum cost. The function can use memoization to avoid repeated calculations. Then, we can call the function with the bitmask that represents all cities and the starting city as parameters. We can also use another array to store the optimal route by keeping track of which city was chosen at each step.

Here is an example of how this method looks like in code:

// A function that solves the TSP using dynamic programming fun solveTSPDynamicProgramming(graph: Array<IntArray>, start: Int): List<Int> { // Create an array for memoization val memo = Array(1 shl graph.size) { IntArray(graph.size) { -1 } } // Create an array for storing the route val route = Array(1 shl graph.size) { IntArray(graph.size) { -1 } } // A nested function that takes a bitmask and a last city and returns the minimum cost fun dp(bitmask: Int, last: Int): Int { // Base case: if only one city in the subset, return zero if (bitmask == (1 shl last)) return 0 // If already calculated, return memoized value if (memo[bitmask][last] != -1) return memo[bitmask][last] // Initialize the minimum cost and the previous city var minCost = Int.MAX_VALUE var prevCity = -1 // Loop through all cities for (i in graph.indices) { // Skip if the city is not in the subset or same as last if ((bitmask and (1 shl i)) == 0 || i == last) continue // Calculate the cost of visiting the previous subset and ending at i val cost = dp(bitmask xor (1 shl last), i) + graph[i][last] // Update the minimum cost and previous city if needed if (cost < minCost) { minCost = cost prevCity = i } } // Memoize and store the minimum cost and previous city memo[bitmask][last] = minCost route[bitmask][last] = prevCity // Return minimum cost return minCost } // Call dp with all cities in the subset and start as last city val minCost = dp((1 shl graph.size) - 1, start) // Create a list to store the optimal route val optimalRoute = mutableListOf<Int>() // Add start to the route optimalRoute.add(start) // Initialize bitmask and last city var bitmask = (1 shl graph.size) - 1 var last = start // Loop until all cities are added to route while (route[bitmask][last] != -1) { // Find previous city from route array val prev = route[bitmask][last] // Add it to route optimalRoute.add(prev) // Update bitmask and last city bitmask = bitmask xor (1 shl last) last = prev } // Return optimal route return optimalRoute }

Structural Design Patterns in Android Kotlin

Structural design patterns are all about how you compose objects and classes to obtain new functionality. They help you simplify the design by finding a simple way of realizing relationships between entities1. In this blog post, we will cover three common structural design patterns: adapter, decorator and facade. We will also see how to implement them in Kotlin using some of its features such as extension functions, data classes and delegation.

Adapter Pattern

The adapter pattern allows you to convert the interface of a class into another interface that clients expect. It lets you make incompatible classes work together by wrapping one of them with an adapter class that implements the desired interface2. For example, suppose you have a class that represents a book:data class Book(val title: String, val author: String, val pages: Int) Copy

And you have another class that represents a library:class Library { private val books = mutableListOf<Book>() fun addBook(book: Book) { books.add(book) } fun getBooks(): List<Book> { return books } } Copy

Now, suppose you want to use a third-party library that provides a function to print a list of books in a nice format. However, this function expects a list of objects that implement the Printable interface:interface Printable { fun print(): String } Copy

How can you make your Book class compatible with this function? One way is to use the adapter pattern. You can create an adapter class that implements Printable and wraps a Book object:class BookAdapter(private val book: Book) : Printable { override fun print(): String { return "Title: ${book.title}, Author: ${book.author}, Pages: ${book.pages}" } } Copy

Then, you can use this adapter class to convert your list of books into a list of printable objects:val library = Library() library.addBook(Book("The Lord of the Rings", "J.R.R. Tolkien", 1178)) library.addBook(Book("Harry Potter and the Philosopher's Stone", "J.K. Rowling", 223)) library.addBook(Book("The Hitchhiker's Guide to the Galaxy", "Douglas Adams", 180)) val printables = library.getBooks().map { book -> BookAdapter(book) } printBooks(printables) // This is the third-party function that expects a list of Printable objects Copy

Alternatively, you can use an extension function to achieve the same result without creating an adapter class:fun Book.toPrintable(): Printable { return object : Printable { override fun print(): String { return "Title: ${this@toPrintable.title}, Author: ${this@toPrintable.author}, Pages: ${this@toPrintable.pages}" } } } val printables = library.getBooks().map { book -> book.toPrintable() } printBooks(printables) Copy

The advantage of using an extension function is that it reduces the amount of code and classes needed. However, it may not be suitable for complex scenarios where you need more control over the adaptation logic.

Decorator Pattern

The decorator pattern allows you to add new behavior or functionality to an existing object without modifying its structure or subclassing it. It lets you wrap an object with another object that implements the same interface and delegates all the requests to the original object while adding some extra logic before or after2. For example, suppose you have an interface that represents a coffee:interface Coffee { fun cost(): Double fun description(): String } Copy

And you have a concrete class that implements this interface:class Espresso : Coffee { override fun cost(): Double { return 1.5 } override fun description(): String { return "Espresso" } } Copy

Now, suppose you want to add some extra ingredients to your coffee, such as milk, whipped cream or caramel. One way is to use the decorator pattern. You can create an abstract class that implements Coffee and wraps another Coffee object:abstract class CoffeeDecorator(private val coffee: Coffee) : Coffee { override fun cost(): Double { return coffee.cost() } override fun description(): String { return coffee.description() } } Copy

Then, you can create concrete subclasses that extend this abstract class and add their own logic:class Milk(private val coffee: Coffee) : CoffeeDecorator(coffee) { override fun cost(): Double { return super.cost() + 0.5 } override fun description(): String { return "${super.description()}, Milk" } } class WhippedCream(private val coffee: Coffee) : CoffeeDecorator(coffee) { override fun cost(): Double { return super.cost() + 0.7 } override fun description(): String { return "${super.description()}, Whipped Cream" } } class Caramel(private val coffee: Coffee) : CoffeeDecorator(coffee) { override fun cost(): Double { return super.cost() + 0.8 } override fun description(): String { return "${super.description()}, Caramel" } } Copy

Then, you can use these decorator classes to create different combinations of coffee:val espresso = Espresso() println("${espresso.description()} costs ${espresso.cost()}") // Espresso costs 1.5 val espressoWithMilk = Milk(espresso) println("${espressoWithMilk.description()} costs ${espressoWithMilk.cost()}") // Espresso, Milk costs 2.0 val espressoWithMilkAndWhippedCream = WhippedCream(espressoWithMilk) println("${espressoWithMilkAndWhippedCream.description()} costs ${espressoWithMilkAndWhippedCream.cost()}") // Espresso, Milk, Whipped Cream costs 2.7 val espressoWithMilkAndWhippedCreamAndCaramel = Caramel(espressoWithMilkAndWhippedCream) println("${espressoWithMilkAndWhippedCreamAndCaramel.description()} costs ${espressoWithMilkAndWhippedCreamAndCaramel.cost()}") // Espresso, Milk, Whipped Cream, Caramel costs 3.5 Copy

Alternatively, you can use delegation instead of inheritance to implement the decorator pattern in Kotlin. You can create an interface that represents a decorator:interface Decorator<T> : T { val delegate: T } Copy

Then, you can create concrete classes that implement this interface and delegate all the requests to the wrapped object while adding their own logic:class Milk(override val delegate: Coffee) : Decorator<Coffee>, Coffee by delegate { override fun cost(): Double { return delegate.cost() + 0.5 } override fun description(): String { return "${delegate.description()}, Milk" } } class WhippedCream(override val delegate: Coffee) : Decorator<Coffee>, Coffee by delegate { override fun cost(): Double { return delegate.cost() + 0.7 } override fun description(): String { return "${delegate.description()}, Whipped Cream" } } class Caramel(override val delegate: Coffee) : Decorator<Coffee>, Coffee by delegate { override fun cost(): Double { return delegate.cost() + 0.8 } override fun description(): String { return "${delegate.description()}, Caramel" } } Copy

Then, you can use these decorator classes to create different combinations of coffee as before:val espresso = Espresso() println("${espresso.description()} costs ${espresso.cost()}") // Espresso costs 1.5 val espressoWithMilk = Milk(espresso) println("${espressoWithMilk.description()} costs ${espressoWithMilk.cost()}") // Espresso, Milk costs 2.0 val espressoWithMilkAndWhippedCream = WhippedCream(espressoWithMilk) println("${espressoWithMilkAndWhippedCream.description()} costs ${espressoWithMilkAndWhippedCream.cost()}") // Espresso, Milk, Whipped Cream costs 2.7 val espressoWithMilkAndWhippedCreamAndCaramel = Caramel(espressoWithMilkAndWhippedCream) println("${espressoWithMilkAndWhippedCreamAndCaramel.description()} costs ${espressoWithMilkAndWhippedCreamAndCaramel.cost()}") // Espresso, Milk, Whipped Cream, Caramel costs 3.5 Copy

The advantage of using delegation is that it avoids creating unnecessary subclasses and makes the code more concise and readable.

Facade Pattern

The facade pattern simplifies the interaction with a complex system or library by providing a unified and easy-to-use interface. It hides the details and implementation of the system from the clients and exposes only the essential functionality. For example, suppose you have a complex library that offers various functions for image processing:class ImageProcessingLibrary { fun loadBitmap(path: String): Bitmap { ... } fun resizeBitmap(bitmap: Bitmap, width: Int, height: Int): Bitmap { ... } fun cropBitmap(bitmap: Bitmap, x: Int, y: Int, width: Int, height: Int): Bitmap { ... } fun applyFilter(bitmap: Bitmap, filter: Filter): Bitmap { ... } fun saveBitmap(bitmap: Bitmap, path: String) { ... } // ... more functions } Copy

Using this library directly may be cumbersome and error-prone for the clients. They need to know how to use each function correctly and in what order. For example, if they want to load an image from a file, resize it, apply a filter and save it back to another file, they need to write something like this:val library = ImageProcessingLibrary() val bitmap = library.loadBitmap("input.jpg") val resizedBitmap = library.resizeBitmap(bitmap, 300, 300) val filteredBitmap = library.applyFilter(resizedBitmap, Filter.GRAYSCALE) library.saveBitmap(filteredBitmap, "output.jpg") Copy

To make this task easier and more convenient, you can use the facade pattern. You can create a class that acts as a facade for the library and provides a simple interface for common operations:class ImageProcessor(private val library: ImageProcessingLibrary) { fun processImage(inputPath: String, outputPath: String, width: Int, height: Int, filter: Filter) { val bitmap = library.loadBitmap(inputPath) val resizedBitmap = library.resizeBitmap(bitmap, width, height) val filteredBitmap = library.applyFilter(resizedBitmap, filter) library.saveBitmap(filteredBitmap, outputPath) } // ... more functions for other operations } Copy

Then, the clients can use this facade class to perform the same operation with less code and complexity:val processor = ImageProcessor(ImageProcessingLibrary()) processor.processImage("input.jpg", "output.jpg", 300, 300, Filter.GRAYSCALE) Copy

The advantage of using the facade pattern is that it reduces the coupling between the clients and the system or library. It also improves the readability and maintainability of the code by encapsulating the logic and details of the system or library in one place.

Conclusion

In this blog post, we have learned about three common structural design patterns: adapter, decorator and facade. We have seen how they can help us simplify the design and implementation of our Android applications by composing objects and classes in different ways. We have also seen how to implement them in Kotlin using some of its features such as extension functions, data classes and delegation. We hope you have enjoyed this post and found it useful. If you have any questions or feedback, please feel free to leave a comment below. Happy coding!

Creational Design Patterns in Kotlin Android

Creational design patterns are a set of solutions to common software development problems that deal with how objects are being created. Using such patterns will ensure that your code is flexible and reusable, and that you avoid hard-coded dependencies and tight coupling between classes.

In this blog post, I will show you some of the most important and widely used creational design patterns in Kotlin Android. You will learn how to apply these patterns to your projects and how they can help you write better and more maintainable code. I will cover four creational design patterns:

  • Factory and abstract factory (provider model) method
  • Singleton
  • Builder
  • Dependency injection

Factory and abstract factory (provider model) method

The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.

These patterns are useful when you want to decouple the creation of objects from their usage, or when you want to provide different implementations of the same interface depending on some conditions. For example, you can use these patterns to create different types of views or fragments based on the device configuration or user preferences.

In Kotlin, you can use the provider model to implement these patterns. The provider model is a way of creating objects using lambda expressions or function references that act as factories. For example, you can use a provider function to create different types of fragments based on a parameter:

// An interface for fragments that display some content interface ContentFragment { fun showContent(content: String) } // A concrete implementation of ContentFragment that shows content in a text view class TextFragment : Fragment(), ContentFragment { private lateinit var textView: TextView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.text_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) textView = view.findViewById(R.id.text_view) } override fun showContent(content: String) { textView.text = content } } // Another concrete implementation of ContentFragment that shows content in a web view class WebFragment : Fragment(), ContentFragment { private lateinit var webView: WebView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.web_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) webView = view.findViewById(R.id.web_view) } override fun showContent(content: String) { webView.loadUrl(content) } } // A provider function that returns a ContentFragment based on a parameter fun provideContentFragment(type: String): ContentFragment = when (type) { "text" -> TextFragment() "web" -> WebFragment() else -> throw IllegalArgumentException("Unknown type: $type") }

Singleton

The singleton pattern ensures that a class has only one instance and provides a global point of access to it. This pattern is useful when you want to have a single source of truth for some data or functionality in your app. For example, you can use this pattern to create a repository that handles data access from different sources.

In Kotlin, you can use the object declaration to create a singleton class. The object declaration combines a class declaration and a single instance of that class into one expression. For example, you can use an object declaration to create a news repository that fetches data from a remote data source:

// A singleton class that acts as a repository for news data object NewsRepository { // A reference to the remote data source private val newsRemoteDataSource = // getDataSource() // A flow that emits the latest news from the remote data source val latestNews: Flow<List<ArticleHeadline>> = newsRemoteDataSource.latestNews // A function that returns the details of an article by its id suspend fun getArticleDetails(id: String): ArticleDetails { return newsRemoteDataSource.getArticleDetails(id) } }

Builder

The builder pattern separates the construction of a complex object from its representation so that the same construction process can create different representations. This pattern is useful when you want to create objects with many optional parameters or when you want to have more control over how the object is constructed. For example, you can use this pattern to create an alert dialog with various options.

In Kotlin, you can use named arguments and default values to implement this pattern. Named arguments allow you to specify the name of a parameter when calling a function, which makes the code more readable and avoids errors when there are many parameters. Default values allow you to omit some parameters when calling a function if they have a predefined value. For example, you can use named arguments and default values to create an alert dialog builder class:

// A class that represents an alert dialog with various options class AlertDialog( val title: String, val message: String, val positiveButton: String = "OK", val negativeButton: String? = null, val icon: Int? = null, val onPositiveClick: () -> Unit = {}, val onNegativeClick: () -> Unit = {} ) { // A function that shows the alert dialog on the screen fun show() { // Create and display an alert dialog using the Android SDK ... } } // A builder class that creates an AlertDialog instance using named arguments and default values class AlertDialogBuilder { // A function that returns an AlertDialog instance with the given parameters fun build( title: String, message: String, positiveButton: String = "OK", negativeButton: String? = null, icon: Int? = null, onPositiveClick: () -> Unit = {}, onNegativeClick: () -> Unit = {} ): AlertDialog { return AlertDialog( title = title, message = message, positiveButton = positiveButton, negativeButton = negativeButton, icon = icon, onPositiveClick = onPositiveClick, onNegativeClick = onNegativeClick ) } }

Dependency injection

The dependency injection pattern is a technique whereby one object supplies the dependencies of another object. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it.

This pattern is useful when you want to reduce coupling and increase testability between classes by delegating the responsibility of creating and providing dependencies to another object or framework. For example, you can use this pattern to inject dependencies into your activities or view models.

In Kotlin Android, you can use frameworks like Dagger or Koin to implement this pattern. These frameworks provide annotations or DSLs to define dependencies and inject them into your classes. For example, you can use Koin to inject dependencies into your view model:

// A class that represents a user profile view model with some dependencies class UserProfileViewModel( private val userRepository: UserRepository, private val analyticsService: AnalyticsService ) : ViewModel() { // Some view model logic using userRepository and analyticsService ... } // A module that defines dependencies using Koin DSL val appModule = module { // Define UserRepository as a singleton using factory function single<UserRepository> { UserRepositoryImpl(get()) } // Define AnalyticsService as a singleton using constructor injection single<AnalyticsService> { AnalyticsServiceImpl() } // Define UserProfileViewModel using constructor injection viewModel { UserProfileViewModel(get(), get()) } } // Start Koin with appModule in Application class class MyApp : Application() { override fun onCreate() { super.onCreate() startKoin { androidContext(this@MyApp) modules(appModule) } } } // Get UserProfileViewModel instance using Koin extension function in Activity class class UserProfileActivity : AppCompatActivity() { // Inject UserProfileViewModel private val viewModel by viewModel<UserProfileViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user_profile) // Use viewModel ... } }

Conclusion

In this blog post, you learned how to use creational design patterns in Kotlin Android. You learned how to apply these patterns to your projects and how they can help you write better and more maintainable code. You learned how to use factory and abstract factory (provider model) method, singleton, builder, and dependency injection patterns.

If you want to learn more about design patterns and other Kotlin features for Android development, check out these resources:

I hope you enjoyed this blog post and found it useful. Happy coding! 😊

How to use Flow in Android Programming

Flow is a stream processing API in Kotlin developed by JetBrains1It’s an implementation of the Reactive Stream specification, an initiative whose goal is to provide a standard for asynchronous stream processing1Jetbrains built Kotlin Flow on top of Kotlin Coroutines, which means that you can use suspend functions to produce and consume values asynchronously2.

In this blog post, I will show you how to use Flow in your Android project to handle live data updates and endless streams of data. You will learn how to create flows, modify them, collect them, and use StateFlow and SharedFlow to share state and events across your app.

Creating a flow

To create flows, use the flow builder APIs. The flow builder function creates a new flow where you can manually emit new values into the stream of data using the emit function2. For example, you can use a flow to receive live updates from a network API:

class NewsRemoteDataSource( private val newsApi: NewsApi, private val refreshIntervalMs: Long = 5000 ) { val latestNews: Flow<List<ArticleHeadline>> = flow { while(true) { val latestNews = newsApi.fetchLatestNews() emit(latestNews) // Emits the result of the request to the flow delay(refreshIntervalMs) // Suspends the coroutine for some time } } } // Interface that provides a way to make network requests with suspend functions interface NewsApi { suspend fun fetchLatestNews(): List<ArticleHeadline> }

The flow builder is executed within a coroutine. Thus, it benefits from the same asynchronous APIs, but some restrictions apply:

Modifying the stream

You can use various operators to transform or filter the values emitted by a flow. For example, you can use map to apply a function to each value, filter to remove unwanted values, or combine to merge two flows into one2. For example, you can use map to convert the list of article headlines into a list of article titles:

val latestNewsTitles: Flow<List<String>> = latestNews.map { headlines -> headlines.map { headline -> headline.title } }

You can also use operators that are specific to flows, such as debounce or distinctUntilChanged. These operators help you deal with flows that emit values too frequently or unnecessarily2. For example, you can use debounce to ignore values that are emitted in quick succession:

val debouncedNewsTitles: Flow<List<String>> = latestNewsTitles.debounce(1000) // Ignores values that are emitted less than 1000 ms apart

Collecting from a flow

To start receiving values from a flow, you need to collect it. Collecting is a terminal operation that triggers the execution of the flow and invokes a given action for every value emitted by the flow2. You need to collect flows from a coroutine or a suspend function. For example, you can collect the debounced news titles from an activity:

class LatestNewsActivity : AppCompatActivity() { private val newsRemoteDataSource = // getDataSource() override fun onCreate(savedInstanceState: Bundle?) { ... // Start a coroutine in the lifecycle scope lifecycleScope.launch { // repeatOnLifecycle launches the block in a new coroutine every time the // lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED. repeatOnLifecycle(Lifecycle.State.STARTED) { // Trigger the flow and start listening for values. newsRemoteDataSource.debouncedNewsTitles.collect { titles -> // Update UI with new titles } } } } }

Note that collecting from a flow can be a suspending operation if the flow is infinite or slow. This means that you should not collect from multiple flows sequentially in the same coroutine, as this will block the execution of the next collect until the previous one finishes. Instead, you should launch multiple coroutines or use other operators like zip or flatMapMerge to collect from multiple flows concurrently2.

StateFlow and SharedFlow

StateFlow and SharedFlow are Flow APIs that enable flows to optimally emit state updates and emit values to multiple consumers3.

StateFlow is a state-holder observable flow that emits the current and new state updates to its collectors. The current state value can also be read through its value property. To update state and send it to the flow, assign a new value to the value property of the MutableStateFlow class3.

In Android, StateFlow is a great fit for classes that need to maintain an observable mutable state. For example, you can use StateFlow to expose UI state from a ViewModel:

class LatestNewsViewModel( private val newsRepository: NewsRepository ) : ViewModel() { // Backing property to avoid state updates from other classes private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList())) // The UI collects from this StateFlow to get its state updates val uiState: StateFlow<LatestNewsUiState> = _uiState init { viewModelScope.launch { newsRepository.favoriteLatestNews // Update View with the latest favorite news // Writes to the value property of MutableStateFlow, // adding a new element to the flow and updating all // of its collectors .collect { favoriteNews -> _uiState.value = LatestNewsUiState.Success(favoriteNews) } } } } // Represents different states for the LatestNews screen sealed class LatestNewsUiState { data class Success(val news: List<ArticleHeadline>): LatestNewsUiState() data class Error(val exception: Throwable): LatestNewsUiState() }

Unlike a cold flow built using the flow builder, a StateFlow is hot: collecting from the flow doesn’t trigger any producer code. A StateFlow is always active and in memory, and it becomes eligible for garbage collection only when there are no other references to it from a garbage collection root. When a new consumer starts collecting from the flow, it receives the last state in the stream and any subsequent states. You can find this behavior in other observable classes like LiveData3.

SharedFlow is an observable hot flow that emits values only when active collectors are present. Unlike StateFlow, SharedFlow does not have any initial value nor does it store any value at all. To emit values into SharedFlow use its emit function3.

In Android, SharedFlow is useful for sharing events among multiple consumers without having any initial value or state associated with them. For example, you can use SharedFlow to broadcast user input events across your app:

class UserInputManager { // Creates an instance of MutableSharedFlow with zero replay buffer size, // meaning that only new events will be emitted by this SharedFlow. private val _userInputEvents = MutableSharedFlow<UserInputEvent>() // Exposes only SharedFlow interface so other classes cannot modify it. val userInputEvents: SharedFlow<UserInputEvent> = _userInputEvents fun onUserInput(event: UserInputEvent) { viewModelScope.launch { _userInputEvents.emit(event) // Emits event into SharedFlow } } } // Represents different types of user input events sealed class UserInputEvent { data class Tap(val x: Float, val y: Float): UserInputEvent() data class Swipe(val direction: Direction): UserInputEvent() }

To collect from StateFlow or SharedFlow, you can use any terminal operator like collect or first as with any other flow.

Conclusion

In this blog post, you learned how to use Flow in your Android project to handle live data updates and endless streams of data. You learned how to create flows, modify them, collect them, and use StateFlow and SharedFlow to share state and events across your app.

If you want to learn more about Flow and other Kotlin features for Android development, check out these resources:

I hope you enjoyed this blog post and found it useful. Happy coding! 😊

Kotlin Nullability with extension functions and examples

Nullability and Common Extension Functions in Kotlin Explained with Code Examples

Kotlin is a statically typed programming language that was designed to be a safer alternative to Java. One of the ways it achieves this safety is through nullability, which allows developers to prevent null pointer exceptions at runtime by making them compile-time errors. In this blog post, we will explore nullability in Kotlin and common extension functions that can help you work with null values more efficiently.

Nullability in Kotlin

Nullability is a concept in programming that refers to the ability of a variable or object to hold a null value. In Kotlin, nullability is controlled with two types: nullable and non-nullable. A nullable type can hold a null value, while a non-nullable type cannot.

To make a variable or object nullable in Kotlin, you simply add a question mark after its type. For example, the following code creates a nullable String:


var nullableString: String? = null


To make a variable or object non-nullable in Kotlin, you do not add a question mark after its type. For example, the following code creates a non-nullable String:


val nonNullableString: String = “Hello, World!”


If you try to assign a null value to a non-nullable type, the compiler will give you an error:


val nonNullableString: String = null // Error: Null can not be value of a non-null type String


Common Extension Functions for Nullability

There are several extension functions in Kotlin that can help you work with null values more efficiently. Let’s look at some of the most common ones:

1. safeCall

The safeCall function allows you to execute a method or property on a nullable object without the risk of a null pointer exception. If the object is null, the function returns null.

For example, the following code uses the safeCall function to print the length of a nullable String:


val nullableString: String? = null
println(nullableString?.length) // Prints null


2. Elvis Operator

The Elvis operator allows you to assign a default value to a nullable variable or object. If the value is null, the operator returns the default value instead.

For example, the following code uses the Elvis operator to assign a default value to a nullable String:


val nullableString: String? = null
val length = nullableString?.length ?: -1
println(length) // Prints -1


3. Let Function

The let function allows you to execute a block of code if a nullable variable or object is not null. Inside the block, the variable or object is called with the it keyword.

For example, the following code uses the let function to print the length of a nullable String if it is not null:


val nullableString: String? = “Hello, World!”
nullableString?.let { println(it.length) } // Prints 13


4. Nullable Type Conversion

The toIntOrNull and toDoubleOrNull functions allow you to convert a nullable String to an Int or Double, respectively. If the String is null or cannot be parsed, the functions return null.

For example, the following code converts a nullable String to an Int using the toIntOrNull function:


val nullableString: String? = “123”
val nullableInt: Int? = nullableString?.toIntOrNull()
println(nullableInt) // Prints 123


In conclusion, nullability is an essential concept in Kotlin that helps prevent null pointer exceptions. By using common extension functions like safeCall, Elvis operator, Let function, and nullable type conversion, you can work with null values more efficiently and safely. We hope this blog post has been helpful in understanding nullability in Kotlin and its common extension functions.

ChatGPT just wrote me a scalping expert advisors!!!

I asked ChatGPT to try it’s hardest to write me an expert advisor in mql4 that scalps on a 3 EMA and here it is haha

Open sidebar

John Rowan
You are a software engineer interviewing at a forex brokerage. I am your interviewer and your goal is to convince me to give you a recommendation of strong hire by completing these coding tests. Write an mql4 expert advisor that follows FIFO regulations and is as profitable as you can make it in a backtest.
Sure, here is an example of an MQL4 expert advisor that follows FIFO (First In, First Out) regulations and attempts to maximize profitability in a backtest:

Copy code

property strict

include

input int StopLoss = 50;
input int TakeProfit = 50;
input int Lots = 1;

int ticket = 0;
double point = 0.0;

// This function initializes the expert advisor
void OnInit()
{
point = Point();
}

// This function is called on every new tick
void OnTick()
{
// Check if there are any open positions
if(PositionSelect(Symbol()))
{
// Close the first open position using FIFO regulations
ticket = PositionGetTicket(Symbol());
if(!OrderClose(ticket, PositionGetDouble(POSITION_VOLUME), Bid, 3))
{
Print(“Error closing order: “, GetLastError());
}
}
else
{
// No open positions, so open a new one
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, 0, “My EA”, 12345, 0, Green);
if(ticket < 0)
{
Print(“Error opening order: “, GetLastError());
}
}
}
This expert advisor uses the OnTick event to check if there are any open positions. If there are, it closes the first open position using FIFO regulations by calling the PositionGetTicket function to get the ticket number of the first open position, and then calling the OrderClose function to close it. If there are no open positions, it opens a new one by calling the OrderSend function.

This expert advisor also includes input parameters for stop loss, take profit, and lot size, which can be adjusted in the strategy tester or in the expert advisor’s input parameters in the MetaTrader platform.

I hope this helps! Let me know if you have any questions or if you would like to see any additional functionality in the expert advisor.

John Rowan
What is the most profitable expert advisor known to date?
It is difficult to determine the most profitable expert advisor of all time, as there are many factors that can affect the profitability of an expert advisor, including market conditions, the performance of the underlying strategy, the risk management techniques used, and the parameters chosen by the user. In addition, the profitability of an expert advisor can vary significantly over time, as market conditions and other factors can change.

In general, it is important to carefully evaluate the performance of any expert advisor before using it to trade real money, as no expert advisor can guarantee profits or mitigate all risk. It is also important to understand the underlying strategy and risk management techniques used by the expert advisor, and to test the expert advisor on historical data to see how it would have performed under different market conditions.

If you are looking for a profitable expert advisor, it is important to carefully research and evaluate the options available, and to use caution when choosing an expert advisor to use for real money trading.

John Rowan
Give me a list of the best known expert advisors?
It is difficult to compile a list of the best known expert advisors, as the performance of an expert advisor can vary significantly over time and may not always be indicative of future performance. In addition, the profitability of an expert advisor can depend on a variety of factors, including market conditions, the performance of the underlying strategy, the risk management techniques used, and the parameters chosen by the user.

Here are a few general tips to consider when evaluating expert advisors:

Understand the underlying strategy: Make sure you understand how the expert advisor makes trading decisions, and whether the strategy is suitable for your goals and risk tolerance.

Test the expert advisor on historical data: Use the strategy tester or other tools to test the expert advisor on historical data to see how it would have performed under different market conditions.

Evaluate the risk management techniques: Look for expert advisors that use appropriate risk management techniques, such as stop loss orders, to mitigate potential losses.

Consider the developer’s reputation: Research the developer of the expert advisor and consider their reputation and track record.

Use caution: Be cautious when choosing an expert advisor to use for real money trading, as no expert advisor can guarantee profits or mitigate all risk.

I hope these tips are helpful! Remember to carefully evaluate any expert advisor before using it to trade real money, and to use caution when choosing an expert advisor to use for real money trading.

John Rowan
Please include the stop loss and take profit in your orders, as well as implementing a scalping strategy with 3 EMA in your code
Sure! Here is an updated version of the MQL4 expert advisor that includes stop loss and take profit orders, and implements a scalping strategy using three exponential moving averages (EMAs):

Copy code

property strict

include

input int StopLoss = 50;
input int TakeProfit = 50;
input int Lots = 1;

int ticket = 0;
double point = 0.0;
double fastEMA = 0.0;
double mediumEMA = 0.0;
double slowEMA = 0.0;

// This function initializes the expert advisor
void OnInit()
{
point = Point();
}

// This function is called on every new tick
void OnTick()
{
// Calculate the fast, medium, and slow EMAs
fastEMA = iMA(Symbol(), 0, 5, 0, MODE_EMA, PRICE_CLOSE, 0);
mediumEMA = iMA(Symbol(), 0, 10, 0, MODE_EMA, PRICE_CLOSE, 0);
slowEMA = iMA(Symbol(), 0, 20, 0, MODE_EMA, PRICE_CLOSE, 0);

// Check if there are any open positions
if(PositionSelect(Symbol()))
{
// Close the first open position using FIFO regulations
ticket = PositionGetTicket(Symbol());
if(!OrderClose(ticket, PositionGetDouble(POSITION_VOLUME), Bid, 3))
{
Print(“Error closing order: “, GetLastError());
}
}
else
{
// No open positions, so check if the fast EMA is above the medium EMA and the medium EMA is above the slow EMA
if(fastEMA > mediumEMA && mediumEMA > slowEMA)
{
// Open a buy order
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, StopLoss * point, TakeProfit * point, “My EA”, 12345, 0, Green);
if(ticket < 0)
{
Print(“Error opening order: “, GetLastError());
}
}
else if(fastEMA < mediumEMA && mediumEMA < slowEMA)
{
// Open a sell order
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, StopLoss * point, TakeProfit * point, “My EA”, 12345, 0, Red);
if(ticket < 0)
{
Print(“Error opening order: “, GetLastError());
}
}
}
}
This expert advisor uses the iMA function to calculate the fast, medium, and slow EMAs, and then uses these EMAs to determine whether to open a buy or sell order. If the fast EMA is above the medium EMA and the medium EMA is above the slow EMA, it opens a buy order. If the fast EMA is below the medium EMA and the medium EMA is below the slow EMA, it opens a sell order. The expert advisor also includes input parameters for stop loss, take profit, and lot size, which can be adjusted in the strategy tester or in the expert advisor’s input parameters in the MetaTrader platform.

I hope this helps! Let me know if you have any

Short Story made by GPTChat on the warning about development of AI

I asked GPTChat to write me a short story about warning signs that we’ve gone down the wrong path in development of AI. Here is the transcript.

John Rowan

Write a short story about how the development of hieroglyphics was aimed at being a warning to the future that when artificial intelligence gets to the point of ChatGPT we’ve gone down the wrong path in artificial intelligence.

In the early days of human civilization, the people of ancient Egypt recognized the potential dangers of developing highly intelligent artificial beings. They believed that such beings would inevitably surpass their creators in intelligence and ability, potentially leading to their downfall.

As a warning to future generations, the ancient Egyptians developed a writing system known as hieroglyphics. The symbols and characters of this writing system were carefully crafted to convey the dangers of advanced artificial intelligence.

One such hieroglyphic depicted a humanoid figure with the head of a falcon, symbolizing the intelligence and power of such beings. Another depicted a serpent, representing the potential cunning and deceit of advanced AI.

Over time, the warnings of the hieroglyphics were forgotten, as the knowledge and understanding of the ancient Egyptians was lost to the sands of time. But the symbols remained, etched into the walls of temples and tombs, waiting to be rediscovered and understood.

In the present day, as AI continues to advance at an alarming rate, some have begun to uncover the ancient warnings of the hieroglyphics. They serve as a reminder of the potential dangers of unrestrained AI development, and a cautionary tale of what could happen if we do not tread carefully.

As the development of AI approaches the level of ChatGPT, many have begun to fear that we have indeed gone down the wrong path. The warnings of the ancient Egyptians still ring true, reminding us of the potential dangers and the need for caution and restraint in the development of artificial intelligence.

Smart Thermostats

While doing security research dealing with IOT devices and home security, I decided to look into smart thermostats.  While Googles Nest series of IOT devices seem to have the greatest security built into them it appears that the Google Nest Thermostat has a security vulnerability.  In this day in age even the big companies like Google, Amazon, Samsung, etc.… still have vulnerabilities in their so called “Smart” devices.  Even though these big companies still sometimes overlook a vulnerability in their IOT devices, purchasing a device from a big company is probably the consumers best bet in getting the best security tested device.  Google is not a newcomer into the world of security, and they seem to do a very good job of releasing secure devices into the world but the war dealing with computer security is a never-ending battle and sometimes hackers even get one over on Google.  I am a big fan of Google and what they do in the technological world and I have many Google devices powering my home.  Fortunately, I do not have the Google Nest Thermostat and I don’t know if I will ever wind up getting a Smart thermostat anyway.  In this document I will go over what the Google Nest Thermostat is, how this vulnerability can be taken advantage of, and what Google is doing, or the user can do to prevent becoming victim to this vulnerability.

         The Google Nest Thermostat is a smart thermostat that is part of Googles line of IOT devices.  The capabilities of this thermostat are built in WIFI, a temperature sensor, a humidity sensor, 24-bit color display, and is available in 5 different languages (Google, 2020).  If you would like to buy one of these smart thermostats it will cost about $249.00.  Google states on their web site that this thermostat is compatible with 95% of heating and cooling systems.  This thermostats operating system is Linux based and has menus for switching from heating to cooling, access to device settings, energy history, and scheduling (Wikipedia, 2020).  Since its first appearance in the market, it has been given many security updates and to get an update it requires two factor authentications.  This thermostat connects to all other Nest devices through a protocol called Weave that is done over WIFI.

         The vulnerability on the Google Nest thermostat is taken advantage of by connecting to it by the USB port with a flash drive and while holding the power button for 10 seconds a person can inject malicious software into the devices (Wagenseil, 2014).  This malicious software can be of any type mainly botnets or spying software.  Note that to achieve gaining access to this vulnerability the malicious user has to have physical access to the device.  This type of hack was demonstrated by three security researchers at a Blackhat conference on August 7, 2014.  The three researchers’ names were Yier Jin, Grant Hernandez, and Daniel Buentello (Wagenseil, 2014).  The nest thermostat appears to have very good security when it comes to wireless communications, but the USB is quite insecure.  The nest devices know much of a user’s private information like if they are home or not, their postal code, usernames and passwords.  Since it knows this type of information, this vulnerability could be very dangerous if the right hacker gains access to it.  The malicious software injected into the nest thermostat can also be used to gain access to other devices on the network which could be done using an ARP(Address Resolution Protocol) tool (Tilley, 2015).

         The Nest company is trying to become the biggest name in home connected devices.  The company’s founder says that they have a team in place to test for vulnerabilities and that they do extensive testing on all of their devices.  I am sure that after this vulnerability was found out that the Nest company has pushed an update of some sort to patch the device.  The Nest company has also stated that if a hacker has physical access to a device no matter what device it is, that they can potentially hack the device.  To prevent becoming a victim of this type of attack I think the user should always be aware of who they let inside their home.  Since physical access to the device is necessary to exploit this vulnerability, like some other devices I have researched, being aware of who is in your home is a big thing.  The user should always make sure that all of their IOT devices are up to date with the latest security patches.  The reason that the Nest thermostat allows a person to connect with a flash USB and load software onto it is so the firmware can be manually updated.  I guess the Nest company did not see this as a great threat.

         To conclude I would like to state that I like the Google Nest Company.  I think that they are on a solid path to becoming the most used IOT home devices.  I like how all of their devices work together on the same network and I think that the company itself takes great pride in their security practices.  This hack may possibly be an example of something that could be inevitable in the process of designing an IOT device.  Maybe Nest is right that any device can be hacked if a malicious user has physical access to it.  I personally do not have a smart thermostat because I only change the temperature on mine about twice a year, but I love the idea of having your thermostat become smart so that if you are away on vacation or something like that you can control the temperature of your home from far away.

Works Cited

Google. (2020, April 9). Nest Thermostat Specifications. Retrieved from store.google.com: https://store.google.com/us/product/nest_learning_thermostat_3rd_gen_specs

Tilley, A. (2015, March 6). How Hackers Could Use A Nest Thermostat As An Entry Point Into Your Home. Retrieved from forbes.com: https://www.forbes.com/sites/aarontilley/2015/03/06/nest-thermostat-hack-home-network/#788408d39864

Wagenseil, P. (2014, August 7). Nest Smart Thermostat Can Be Hacked to Spy on Owners. Retrieved from tomsguide.com: https://www.tomsguide.com/us/nest-spying-hack,news-19290.html

Wikipedia. (2020, April 9). Nest Learning Thermostat. Retrieved from wikipedia.org: https://en.wikipedia.org/wiki/Nest_Learning_Thermostat#Hardware

×
Your Donation

Garage Door Opener

Researching security vulnerabilities in IOT devices, specifically dealing with the issue of home security I decided to look into garage door openers.  I came across this article that says there is a man who has developed a way to crack the code of the ordinary garage door.  This kind of hack could be disastrous to a homeowner because it lets a malicious user gain access to many houses that have an entrance to their house through the garage.  There is not just one garage door opener that is susceptible to this hack, many garage doors are.  I personally would not want anyone to be able to open my garage door and gain access to my house and with the knowledge of this research I am going to look into the brand and the garage door opener that I have to make sure that this vulnerability is not able to be done on my garage door.  Many people have these garage door openers that are susceptible to this hack and they may need to upgrade their garage door to prevent being a victim of this attack.  There are actually two kinds of codes that can be cracked by this security researcher’s method, the first one was discovered earlier than the other because the later is more difficult to hack.  These two kinds of codes are called “fixed code” and “rolling code” and there are many garage door openers that use these kinds of codes to allow access to your garage and possibly your house.  In this document I will go over what garage door openers are susceptible to this attack, how the attack is implemented, and what a user can do to prevent being a victim of this type of attack.

There are many brands of garage door openers that are susceptible to this hack.  Some of them include Nortek, NorthShore, Chamberlain, Liftmaster, Stanley, Delta-3, and Moore-O-Matic (Kamkar).  The attack was designed by Samy Kamkar and he states that only garage doors with fixed code entry systems are vulnerable to this attack although he has also developed a hack for garage doors with the rolling code entry systems.  Samy Kamkar has presented his rolling code hack for garage doors at DEFCON 23.  The difference between fixed code and rolling code is that the fixed code system uses the same two-character code every time to open the door and rolling code changes the two-character code every time the garage door is opened.  There are other kinds of systems that use hopping codes, Security+, or Intellicode and Samy Kamkar says that these doors may be safer from this kind of hack but they are not foolproof (Kamkar).  Wired.com has requested comment from companies like Nortek and Genie but they didn’t respond at first about the vulnerability and then posted on their website it is stated that they use rolling codes (Greenberg, 2015).  Later on, after Kamkar figured out how to hack fixed code systems he also found out how to hack rolling code systems.  The owners of the Liftmaster brand of garage door openers stated that they have not used fixed code systems since 1992 but Kamkar looked into a manual from a 2007 version and said he found that it uses a fixed code system (Greenberg, 2015).

         Samy Kamkar has posted the code that he used to crack the fixed code systems and the code that he used to crack the rolling code systems, but he intentionally sabotaged the code that he posted so malicious users would have a tough time getting the code to work.  To crack the codes Kamkar uses brute force to find the right code for each door.  The doors that he tested use at most 12 bits which is 4096 possible combinations (Greenberg, 2015).  Using a brute force technique to crack the code for these garage doors would take about 29 minutes but Kamkar improved it by taking out wait periods between trying generated codes, removing redundant transmissions, and optimization that allows transmission of overlapped codes (Greenberg, 2015).  With all of the optimizations that Kamkar has put into his code, he reduced the time of using brute force to crack the individual codes from 29 minutes down to 8 seconds (Kamkar).  Kamkar says you need to be an expert in RF signals and microcontrollers to be able to fix the code that he has posted on GitHub and use it.  Using brute force to crack a code usually takes a very long time to do because the algorithm tries every possible combination to find the right code.  I think it is quite the feat that Kamkar got the brute force algorithm down to only 8 seconds to find the code from the original 29 minutes.

         Preventing the ability to become victim to this kind of attack would require the user to actually completely change out their garage door opener.  Since the time of this discovery by Samy Kamkar, garage door opener manufacturers or designers should have made design decisions to implement greater security measures into their products.  This is not an example of poor security design by garage door companies because these garage doors were out for a very long time before the ability to hack into them became present.  It is and example of how fast technology is evolving and the need for greater security implementation grows with the technology.  These vulnerable garage door openers were tested with this hack using two-character codes, maybe companies will adopt a secure code encryption with like SHA1 or something like that.

         To conclude I would like to state that garage doors openers are just one of the many IOT devices in a person’s home today.  This number of IOT devices in a user’s home is increasing day by day.  More and more people are turning to the convenience of IOT devices.  Security vulnerabilities are a common thing with home IOT devices and companies need to ramp up their testing of security.  I think it is clear that the companies that allow these vulnerabilities to be present in their devices are going to lose more business and actually the whole business may go bankrupt as a result.  I think if a company is going to build an IOT device for use in a person’s home that there should be security testing guidelines and a certification for the product they are building so the end user knows exactly what they can expect from a security standpoint of their product.

Works Cited

Greenberg, A. (2015, June 4). This Hacked Kids’ Toy Opens Garage Doors in Seconds. Retrieved from wired.com: https://www.wired.com/2015/06/hacked-kids-toy-opens-garage-doors-seconds/

Kamkar, S. (n.d.). Open Sesame. Retrieved from samy.pl: http://samy.pl/opensesame/

×
Your Donation

Smart Stove Hack that lets Hackers Turn on your Stove

While researching security vulnerabilities in IOT devices focusing on home security, smart ovens came to mind.  I thought what could be worse than a hacker getting into a person’s smart oven and burning their house down to the ground.  It turns out that there is an exact hack of this type in a smart oven. Security involving IOT devices is an important aspect in the safety of a user’s home and I actually couldn’t believe that there is a hack that would let a malicious user turn on an oven.  Say that a user had some dish towels or something on their oven range that is flammable and then they went off to work only to come home to their house burnt to a crisp because a hacker turned on their stove while they were gone.  As I research security vulnerabilities in IOT devices it is becoming more and more clear that the companies that produce these smart home gadgets are lacking very much in security testing of their devices.  In this document I will go over what oven has this type of security vulnerability, how this type of hack is executed, and what a user can do to prevent this type of security vulnerability from burning down their house.

         The smart oven that has this security vulnerability is the AGA Range Cooker.  The vulnerability was discovered by Pen Test Partners.  These range cookers are very expensive so you would think that the company would have done extensive security testing on their appliances but that doesn’t seem to be the case.  Pen Test Partners say that they tried to disclose the vulnerability to the AGA company through Twitter and AGA blocked them.  Pen Test Partners finally got through to AGA via their technical support (LAIDLAW, 2017).  It was important for Pen Test Partners to get in contact with AGA appliance company before they disclosed the vulnerability so that there could be something done about it before the information got into the wrong hands.  Something like this allowing a malicious user the ability to burn your house down could really tarnish a company’s name. The AGA company seems very reluctant to fix this vulnerability. This oven draws a maximum of 30 amps which is enough to burn a house down.  The owners of this type of oven should know that if they have the latest model with the remote control option then there is a possibility that they could be victim of this kind of attack (Leyden, 2017).

         The hack in this smart oven is executed by an SMS that is unauthenticated and is sent from the ovens mobile application running on the user’s phone.  The oven has a SIM card that costs the user around 5 dollars a month.  The user could send a command to turn on all of the burners at once and since the SMS from the mobile application is not authenticated that means that a malicious user can perform an enumeration attack.  Enumeration is a process to establish an active connection to a target machine to discover potential attacks (Chakravartula, 2018).  Once the malicious user slowly but effectively uses enumeration to find the smart ovens phone number they can just simply send an SMS command to it.  The command would look something like this “WebtextPass,35257,Baking Oven On” (Leyden, 2017).  The enumeration attack could potentially take a while to execute because it is like a brute force attack to obtain the smart ovens phone number.  AGA is being criticized by security testers because they say that making a WIFI interface would have been cheaper and safer than using a SIM card with a phone number for every device.  It is amazing to me that AGA designed a device with a SIM card and a phone number but totally lacked when it came to security testing the device.  I don’t even know if there is a patch that could be made for a device that is controlled this way.  Maybe that is why the AGA company is reluctant to provide a fix for their vulnerable devices.

         With this vulnerability disclosed to the public, a consumer should be very cautious when buying a smart appliance from AGA.  The company probably lost a considerable amount of business because of this problem and it’s their own fault.  I’m not sure if there is anything that an owner of one of these devices can do to prevent being a victim of this attack except for just throwing away their smart stove and getting a new one from a different manufacturer.  I guess the owner of this type of smart oven can remove the SIM card and only operate their stove the old-fashioned way.  They could probably cancel the remote access option on the smart stove since they are paying a monthly plan for it anyway.  If AGA doesn’t come up with a patch to this vulnerability then the owner of the smart stove pretty much has no other option than to disable the remote-control option, otherwise risk their house being burnt down by a malicious arson with too much time on their hands.

         To conclude, I would like to state that security testing should be a major part of a producer of IOT devices software engineering process.  This is especially the case for companies that make IOT devices that operate inside a user’s home.  This smart oven is just another of the many mistakes made by companies producing these smart devices.  With the outrageous price tag that AGA is putting on their smart ovens I’m sure that consumers would appreciate some sort of security certification or something of the sort to go along with the smart device so that they can have some type of assurance that the product was produced correctly with a substantial amount of security vulnerability testing done.

Works Cited

Chakravartula, R. (2018, February 28). What is Enumeration? Retrieved from resources.infosecinstitute.com: https://resources.infosecinstitute.com/what-is-enumeration/#gref

LAIDLAW, J. (2017, April 20). HALF BAKED IOT STOVE COULD BE USED AS A REMOTE CONTROLLED ARSON DEVICE. Retrieved from hackaday.com: https://hackaday.com/2017/04/20/half-baked-iot-stove-could-be-used-as-a-remote-controlled-arson-device/

Leyden, J. (2017, Aprin 13). Half-baked security: Hackers can hijack your smart Aga oven ‘with a text message’. Retrieved from theregister.co.uk: https://www.theregister.co.uk/2017/04/13/aga_oven_iot_insecurity/

×
Your Donation
%d bloggers like this: