Last Sunday, I submitted my application for the Hennge Back-end(Tokyo, Japan) SDE position. After that, my mail box received a Challenge 3 email from Hennge. The challenge is very interesting. When I had enough free time on this Saturday, I finished this challenge finally. I spent about 3 hours on this. The process is here.
Challenge details
The Challenge link is 403 after I submitted my solution. So, I share the process from my memory. Fortunately, the archive is here: Google Drive.
First, implement a sum of squares of numbers program with Python/Go. You need to implement the input and output process by yourself. Second, create a private github gist with the code. Last, post the gist link to the Hennge server.
The code is very simple. I used Python to implement it. Don’t ignore the instructions in the challenge. Specific rules for Python solution: Do not use any for loop, while loop, or any list / set / dictionary comprehension.
We can use map and reduce in Python to replace the iteration. It is functional programming. If you are familiar with some functional programming languages, like Lisp, you could know that there is no loop syntax existing and the recursive function is the same as the iteration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
```python
```python from functools import reduce
defget_non_negative_square_sum_from_input(): X = int(input()) return reduce(lambda x, y: x + (y * y if y > 0else0), map(int, input().split()), 0)
defmain(): N = int(input()) ans = reduce(lambda x, y: print(get_non_negative_square_sum_from_input()), range(N), [])
if __name__ == "__main__": main()
After struggle with Github two-factor authentication and manual account recovery review, I finally sign in to Github and created my gist, which is secret as required.
I think the hardest part is the authentication POST.
First, I needed to covert the shared secret to TOTP (Time-Based One-Time Password) with RFC 6238. I tried to find a online tool to do that. But unfortunately, the current online tools have a limited options. For example, you can not choose the hash function as HMAC-SHA-512 instead of default HMAC-SHA-1. Therefore, as a result, I wrote a TOTP Generator Online by myself. Hope it could help you. Fortunately, I found a sample Java implementation in the RFC 6238 document. By the way, because the input in the code is a HEX string. I covert my shared secret sen.yang96@outlook.comHENNGECHALLENGE003 to HEX string with a online tool. The challenge required a 10-digits code. The default in the code is 8-digits. I met this response using 8-digits.
I debugged a lot and found that it is the issue of timestamp. Because TOTP is time-based. When I change the timestamp to Instant.now() + 30s, the password passed:
1
{"message":"Congratulations! You have achieved mission 3"}
/** Copyright (c) 2011 IETF Trust and the persons identified as authors of the code. All rights reserved. Redistribution and use in source and binary forms, with or without modification, is permitted pursuant to, and subject to the license terms contained in, the Simplified BSD License set forth in Section 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info). */
/** * This is an example implementation of the OATH * TOTP algorithm. * Visit www.openauthentication.org for more information. * * @author Johan Rydell, PortWise, Inc. */
publicclassTOTP {
privateTOTP() { }
/** * This method uses the JCE to provide the crypto algorithm. * HMAC computes a Hashed Message Authentication Code with the * crypto hash algorithm as a parameter. * * @param crypto: the crypto algorithm (HmacSHA1, HmacSHA256, * HmacSHA512) * @param keyBytes: the bytes to use for the HMAC key * @param text: the message or text to be authenticated */ privatestaticbyte[] hmac_sha(String crypto, byte[] keyBytes, byte[] text) { try { Mac hmac; hmac = Mac.getInstance(crypto); SecretKeySpecmacKey=newSecretKeySpec(keyBytes, "RAW"); hmac.init(macKey); return hmac.doFinal(text); } catch (GeneralSecurityException gse) { thrownewUndeclaredThrowableException(gse); } }
/** * This method converts a HEX string to Byte[] * * @param hex: the HEX string * * @return: a byte array */
privatestaticbyte[] hexStr2Bytes(String hex) { // Adding one byte to get the right conversion // Values starting with "0" can be converted byte[] bArray = newBigInteger("10" + hex, 16).toByteArray();
// Copy all the REAL bytes, not the "first" byte[] ret = newbyte[bArray.length - 1]; for (inti=0; i < ret.length; i++) ret[i] = bArray[i + 1]; return ret; }
/** * This method generates a TOTP value for the given * set of parameters. * * @param key: the shared secret, HEX encoded * @param time: a value that reflects a time * @param returnDigits: number of digits to return * * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */
publicstatic String generateTOTP(String key, String time, String returnDigits) { return generateTOTP(key, time, returnDigits, "HmacSHA1"); }
/** * This method generates a TOTP value for the given * set of parameters. * * @param key: the shared secret, HEX encoded * @param time: a value that reflects a time * @param returnDigits: number of digits to return * * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */
publicstatic String generateTOTP256(String key, String time, String returnDigits) { return generateTOTP(key, time, returnDigits, "HmacSHA256"); }
/** * This method generates a TOTP value for the given * set of parameters. * * @param key: the shared secret, HEX encoded * @param time: a value that reflects a time * @param returnDigits: number of digits to return * * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */
publicstatic String generateTOTP512(String key, String time, String returnDigits) { return generateTOTP(key, time, returnDigits, "HmacSHA512"); }
/** * This method generates a TOTP value for the given * set of parameters. * * @param key: the shared secret, HEX encoded * @param time: a value that reflects a time * @param returnDigits: number of digits to return * @param crypto: the crypto function to use * * @return: a numeric String in base 10 that includes * {@link truncationDigits} digits */
After the congratulations response, I received a link by email to submit my Resume and CV. It was my first time to do the challenge in a job application. I had done some homeworks/assignments and OA tests before. This challenge is so different and interesting. Through it, I learned a lot about TOTP and HTTP authentication.
Unfortunately, the final result is not good. I didn’t get any interview. I knew a few people who applied Hennge too because of this article. No one gets interviews and further progress after this challenge. If you complete the challenge and don’t get good response, it’s not your fault. Hennge seems just don’t hire candidates through the challenge.
Thank you for your interest in Back-End Engineer position at HENNGE and for taking the time to complete the test.
While we were impressed with your background and experience, the selection process was highly competitive and unfortunately we have decided to move forward with another candidate that better fits our requirements at the moment.
Please understand that HENNGE does not provide specific details on the results of the application process.
We wish you the best of luck in your future endeavors.