/** * Calculates hash with algorithm "MD5", "SHA-1" or SHA-256". Hash is calculated EXCLUDING * meta-data, like id3v1 or id3v2 * * @return byte[] hash value in byte * @param String algorithm * @param int buffersize * @throws IOException * @throws InvalidAudioFrameException * @throws NoSuchAlgorithmException */ public byte[] getHash(String algorithm, int bufferSize) throws InvalidAudioFrameException, IOException, NoSuchAlgorithmException { File mp3File = getFile(); long startByte = getMP3StartByte(mp3File); int id3v1TagSize = 0; if (hasID3v1Tag()) { ID3v1Tag id1tag = getID3v1Tag(); id3v1TagSize = id1tag.getSize(); } InputStream inStream = Files.newInputStream(Paths.get(mp3File.getAbsolutePath())); byte[] buffer = new byte[bufferSize]; MessageDigest digest = MessageDigest.getInstance(algorithm); inStream.skip(startByte); int read; long totalSize = mp3File.length() - startByte - id3v1TagSize; int pointer = buffer.length; while (pointer <= totalSize) { read = inStream.read(buffer); digest.update(buffer, 0, read); pointer += buffer.length; } read = inStream.read(buffer, 0, (int) totalSize - pointer + buffer.length); digest.update(buffer, 0, read); byte[] hash = digest.digest(); return hash; }
/** * Saves the tags in this dataType to the file argument. It will be saved as * TagConstants.MP3_FILE_SAVE_WRITE * * @param fileToSave file to save the this dataTypes tags to * @throws FileNotFoundException if unable to find file * @throws IOException on any I/O error */ public void save(File fileToSave) throws IOException { // Ensure we are dealing with absolute filepaths not relative ones File file = fileToSave.getAbsoluteFile(); logger.config("Saving : " + file.getPath()); // Checks before starting write precheck(file); RandomAccessFile rfile = null; try { // ID3v2 Tag if (TagOptionSingleton.getInstance().isId3v2Save()) { if (id3v2tag == null) { rfile = new RandomAccessFile(file, "rw"); (new ID3v24Tag()).delete(rfile); (new ID3v23Tag()).delete(rfile); (new ID3v22Tag()).delete(rfile); logger.config("Deleting ID3v2 tag:" + file.getName()); rfile.close(); } else { logger.config("Writing ID3v2 tag:" + file.getName()); final MP3AudioHeader mp3AudioHeader = (MP3AudioHeader) this.getAudioHeader(); final long mp3StartByte = mp3AudioHeader.getMp3StartByte(); final long newMp3StartByte = id3v2tag.write(file, mp3StartByte); if (mp3StartByte != newMp3StartByte) { logger.config("New mp3 start byte: " + newMp3StartByte); mp3AudioHeader.setMp3StartByte(newMp3StartByte); } } } rfile = new RandomAccessFile(file, "rw"); // Lyrics 3 Tag if (TagOptionSingleton.getInstance().isLyrics3Save()) { if (lyrics3tag != null) { lyrics3tag.write(rfile); } } // ID3v1 tag if (TagOptionSingleton.getInstance().isId3v1Save()) { logger.config("Processing ID3v1"); if (id3v1tag == null) { logger.config("Deleting ID3v1"); (new ID3v1Tag()).delete(rfile); } else { logger.config("Saving ID3v1"); id3v1tag.write(rfile); } } } catch (FileNotFoundException ex) { logger.log( Level.SEVERE, ErrorMessage.GENERAL_WRITE_FAILED_BECAUSE_FILE_NOT_FOUND.getMsg(file.getName()), ex); throw ex; } catch (IOException iex) { logger.log( Level.SEVERE, ErrorMessage.GENERAL_WRITE_FAILED_BECAUSE.getMsg(file.getName(), iex.getMessage()), iex); throw iex; } catch (RuntimeException re) { logger.log( Level.SEVERE, ErrorMessage.GENERAL_WRITE_FAILED_BECAUSE.getMsg(file.getName(), re.getMessage()), re); throw re; } finally { if (rfile != null) { rfile.close(); } } }